Partition

重新安裝一個節點後如何修復缺少塊的 Hadoop HDFS 集群?

  • April 27, 2018

我有一個 5 從屬 Hadoop 集群(使用 CDH4)—從屬是 DataNode 和 TaskNode 執行的地方。每個從屬伺服器有 4 個專用於 HDFS 儲存的分區。其中一個從屬設備需要重新安裝,這導致其中一個 HDFS 分區失去。此時,HDFS 抱怨失去了 35K 塊。

幾天后,重新安裝完成,我將節點重新聯機到 Hadoop。HDFS 仍處於安全模式,並且新伺服器的註冊塊數量不會接近其他節點的數量。例如,在 DFS Admin 下,新節點顯示它有 6K 塊,而其他節點有大約 400K 塊。

目前,新節點的 DataNode 日誌顯示它正在對各種塊進行一些驗證(或複制?),其中一些因已經存在而失敗。我相信這是 HDFS 只是將現有數據複製到新節點。驗證範例:

2013-08-09 17:05:02,113 INFO org.apache.hadoop.hdfs.server.datanode.BlockPoolSliceScanner: Verification succeeded for BP-143510735-141.212.113.141-1343417513962:blk_6568189110100209829_1733272

失敗範例:

2013-08-09 17:04:48,100 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: meez02.eecs.umich.edu:50010:DataXceiver error processing REPLACE_BLOCK operation  src: /141.212.113.141:52192 dest: /141.212.113.65:50010
org.apache.hadoop.hdfs.server.datanode.ReplicaAlreadyExistsException: Block BP-143510735-141.212.113.141-1343417513962:blk_-4515068373845130948_756319 already exists in state FINALIZED and thus cannot be created.
   at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.createTemporary(FsDatasetImpl.java:813)
   at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.createTemporary(FsDatasetImpl.java:92)
   at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.<init>(BlockReceiver.java:155)
   at org.apache.hadoop.hdfs.server.datanode.DataXceiver.replaceBlock(DataXceiver.java:846)
   at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opReplaceBlock(Receiver.java:137)
   at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:70)
   at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:221)
   at java.lang.Thread.run(Thread.java:679)

在 DFS Admin 中,我還可以看到這個新節點的容量為 61%(與其他節點的大致使用情況相匹配),儘管它的塊數約為其他節點的 2%。我猜這只是 HDFS 無法辨識的舊數據。

我懷疑發生了以下幾件事之一:(a)HDFS 由於陳舊而放棄了該節點的數據;(b) 重新安裝更改了一些系統參數,因此 HDFS 將其視為一個全新的節點(即不是現有的有數據的節點);或者 (c) 不知何故,驅動器映射搞砸了,從而導致分區映射被更改,HDFS 無法找到舊數據(儘管驅動器有標籤,我 95% 確定我們做對了)。

**主要問題:**如何讓 HDFS 重新辨識此驅動器上的數據?

  • *答案:*重啟NameNode,節點會重新報告他們擁有哪些區塊(見下面的更新1)

**子問題 1:**如果我對新節點數據使用的假設是正確的——61% 的使用是幽靈數據——它是否曾經被 HDFS 清理過,或者我是否需要手動刪除它?

  • *不太成問題:*因為似乎可以辨識大部分驅動器(請參閱下面的更新 1)

子問題2:listCorruptFileBlocks目前,由於“複製隊列尚未初始化” ,我無法執行查找失去的塊。知道如何解決這個問題嗎?我是否必須等待新節點重新平衡(即此驗證/複製階段結束)?

  • *回答:*離開安全模式讓我執行它(見下面的更新 1)

更新

**更新 1:**我以為我已經通過重新啟動我的 NameNode 解決了這個問題。這導致新節點的塊計數躍升至與其他節點大致相同的使用量,並且 DFS 將其消息更改為:

安全模式已開啟。報告的塊 629047 需要額外的 8172 個塊才能達到總塊 637856 的門檻值 0.9990。安全模式將自動關閉。

我讓它保持這種狀態幾個小時,希望它最終會離開安全模式,但什麼都沒有改變。然後我手動關閉了安全模式,DFS 的消息變為“8800 塊失去”。在這一點上,我能夠執行hdfs fsk -list-corruptfileblocks,查看大部分缺少塊的文件。

*目前剩餘的問題:*如何恢復這些失去的塊……(我應該在新問題中分拆這個嗎?)

我最終不得不刪除帶有壞塊的文件,經過進一步調查,我意識到複製率非常低(如果我沒記錯的話,rep=1)。

這篇 SO 文章有更多關於查找帶有壞塊的文件的資訊,使用以下內容:

hadoop fsck / | egrep -v '^\.+$' | grep -v eplica

所以,回答我自己的問題:

  1. 這些文件可以恢復嗎?除非故障節點/驅動器在失去數據的情況下重新聯機。
  2. 如何退出安全模式?刪除這些麻煩的文件,然後通過dfsadmin.

引用自:https://serverfault.com/questions/530070