目录

HDFS重新格式化的方法

本文仅针对NameNode HA场景,非HA场景可以参考自行验证。

方式1

最简单的就是删掉所有数据目录重走一遍初始化流程。

  • 启动JournalNode
  • 停止主备NameNode
  • 在主NameNode上执行格式化hdfs namenode -format -force 此时会自动格式化NameNode的数据目录,以及所有JournalNode的数据目录
  • 启动主NameNode、ZKFC
  • 在备NameNode上执行hdfs namenode -bootstrapStandby -force
  • 启动备NameNode、ZKFC
  • 手动到每个节点删除DataNode的所有数据目录current文件夹,然后重启DataNode

    如果不进行此操作, DataNode将无法注册到NameNode上,因为current文件夹下VERSION文件存放的clusterID与NameNode的VERSION里的clusterID不一致

  • 此时HDFS功能已经可用

查看报告hdfs dfsadmin -report发现DataNode都已经在线,并且NameNode不在安全模式,即OK

方式2

方式1中最后一步手动删除DataNode的数据目录如果感觉比较麻烦,可以走下面的流程。

  • 启动JournalNode
  • 停止主备NameNode
  • 在NameNode的数据目录,或者DataNode的数据目录的VERSION文件找到clusterID,如CID-5e05a678-fb52-46d7-a097-488f0c02c74e
  • 在主NameNode上执行格式化hdfs namenode -format -force -clusterid CID-5e05a678-fb52-46d7-a097-488f0c02c74e此时会复用了旧的集群ID
  • 启动主NameNode、ZKFC
  • 在备NameNode上执行hdfs namenode -bootstrapStandby -force
  • 启动备NameNode、ZKFC
  • 不需要手动删除DataNode原有的数据目录,直接重启所有DataNode即可
  • 此时HDFS功能已经可用

此时如果到DataNode的数据目录current下会发现,存在2个BP开头的文件夹,如BP-1289061066-192.168.32.11-1663436462170BP-1716800386-192.168.32.11-1665158609367,这是由于刚刚NameNode格式化后VERSION文件里记录的blockpoolID是随机生成的一个新的值,文件夹的名称等同于该值。

由于老的文件夹可能会比较占用空间,可以事后手动删除。相比于方式1,在不删除的情况下已经不阻塞HDFS的正常启动了。如果觉得事后手动删除还是比较麻烦,可以尝试方式3

方式3

此方式有几率存在DataNode或NameNode无法正常工作的情况,不推荐使用

此方式无需手动到每个DataNode节点操作,某些情况下比较方便。

  • 启动JournalNode
  • 停止主备NameNode
  • 在NameNode的数据目录,将整个VERSION文件备份下来。
  • 在主NameNode上执行格式化hdfs namenode -format -force
  • 手动还原刚才备份的VERSION文件。
  • 执行hdfs namenode -initializeSharedEdits -force将还原回来的VERSION文件刷到每个JournalNode上
  • 启动主NameNode,ZKFC
  • 在备NameNode上执行hdfs namenode -bootstrapStandby -force
  • 启动备NameNode、ZKFC
  • 重启所有DataNode
  • 此时HDFS功能已经可用

通过hdfs dfsadmin -report命令可以看到,每个DataNode的Num of Blocks是0,但是仍然占了不少空间DFS Used。但是问题不大,在以后的DataNode心跳上报中,会逐渐将无效块删除,这个空间就会被释放出来。过程会比较漫长,也可以手动挨个对每个DataNode马上触发全量块上报:

hdfs dfsadmin -triggerBlockReport <datanode_host>:<ipc_port>

在收到NameNode的心跳后,会立即删除无效的块,释放出空间。