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-1663436462170、BP-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的心跳后,会立即删除无效的块,释放出空间。