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

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

我有一个 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,以查看缺少块的大部分文件。

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

答案1

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

这篇文章有更多关于如何查找有坏块的文件的信息,使用如下命令:

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

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

  1. 这些文件能恢复吗?除非故障节点/驱动器恢复并恢复丢失的数据,否则不能。
  2. 如何退出安全模式?删除这些麻烦的文件,然后通过 退出安全模式dfsadmin

答案2

我们今天遇到了类似的问题。我们的一个节点(共 3 个,副本数为 3)刚刚死机,重启后,我们开始在受影响的数据节点日志中看到此信息:

18/04/27 14:37:22 INFO datanode.DataNode: Receiving BP-1114663060-172.30.36.22-1516109725438:blk_1073743913_3089 src: /172.30.36.26:35300 dest: /172.30.36.25:50010
18/04/27 14:37:22 INFO datanode.DataNode: g500603svhcm:50010:DataXceiver error processing WRITE_BLOCK operation  src: /172.30.36.26:35300 dst: /172.30.36.25:50010; org.apache.hadoop.hdfs.server.datanode.ReplicaAlreadyExistsException: Block BP-1114663060-172.30.36.22-1516109725438:blk_1073743913_3089 already exists in state FINALIZED and thus cannot be created.

namenodes 的 webui 显示 datanode 只有 92 个块(其余节点共有 13400 个)。

通过在数据节点上触发完整块报告来修复此问题,从而更新了名称节点上的数据:

hdfs dfsadmin -triggerBlockReport g500603svhcm:50020

结果是:数据节点丢失了几个块,但它很高兴地接受了这些块并恢复了集群。

相关内容