如何在重新安装一个节点后修复缺少块的 Hadoop HDFS 集群?

Dol*_*cci 5 partition hadoop hdfs reinstall

我有一个 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
Run Code Online (Sandbox Code Playgroud)

失败示例:

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)
Run Code Online (Sandbox Code Playgroud)

在 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, 查看丢失块的大部分文件。

当前剩余的问题:如何恢复这些丢失的块......(我应该在新问题中解决这个问题吗?)

Dol*_*cci 2

我最终不得不删除带有坏块的文件,经过进一步调查,我意识到复制率非常低(如果我没记错的话,rep=1)。

这篇 SO 文章提供了有关查找带有坏块的文件的更多信息,使用以下内容:

hadoop fsck / | egrep -v '^\.+$' | grep -v eplica
Run Code Online (Sandbox Code Playgroud)

因此,回答我自己的问题:

  1. 这些文件可以恢复吗?除非故障节点/驱动器带着丢失的数据重新上线。
  2. 如何退出安全模式?删除这些麻烦的文件,然后通过 退出安全模式dfsadmin