情景再现:
在修复hadoop集群某一个datanode无法启动的问题时,搜到有一个答案说要删除hdfs-site.xml中dfs.data.dir属性所配置的目录,再重新单独启动该datanode即可;
问题就出在这个误删除上,当时是在namenode的hadoop/hdfs/目录下,然后就执行了一个可怕的命令
rm -rf data
rm -rf name #存储namenode永久性元数据目录
当时还不知道删除这个的可怕,以为只是误删除了普通数据而已,然后再转到datanode下再次执行删除,再启动datanode后就正常了,jps查看各项服务均已正常启动
然后晚上在执行一个job时,报错了,说目录不存在,到此我才意识到是我之前到误删导致到这个错误,当时把datanode节点调试成功后也没试试执行一个job验证hadoop环境到正确性。
然后我就手动建了一个日志说找不到到目录,重启后报错namenode is not formatted,就是说需要格式化namenode才行,到这里就傻眼了,格式化容易,可集群上几个t的数据可能就没了,这很阔怕。
解决历程:
首先重启集群,发现除了namenode外其他均成功启动,这个时候使用
hdfs dfs -ls /
这样的命令去查看hdfs文件系统,是无法查看的,应该是报错被拒绝。
我们去查看
http://192.168.1.148:50070/dfshealth.html#tab-datanode
这个目录,发现是无法访问了,然后再去查看每个数据节点的使用量,使用命令
df -lh
发现几个节点的使用量都不是为0,就是说集群的数据并没有被删除,还有恢复的可能,然后看到了几篇hadoop数据恢复的文章
1,hadoop主节点(NameNode)备份策略以及恢复方法
2,hadoop集群崩溃恢复记录
3,模拟namenode宕机:数据块损坏,该如何修复
还有一篇介绍数据存储的文章
4,hadoop HDFS存储原理
以下是正确的解决方案,耗时一天一夜,首先在本地伪分布式环境测试成功,然后移到集群环境中成功解决:
1、存在一个正常的hadoop环境,hdfs上存在多个文件及文件夹
2、删除name目录
3、stop-all.sh
4、执行namenode格式化操作
hadoop namenode -format
5、复制namesecondary/current下的VERSION文件夹里的三个id(clusterID,namespaceID,blockpoolID)到name/current的VERSION文件相应的值里
6、复制namesecondary/current文件夹下fsimage开头的镜像文件到name到相应目录下
7、start-all.sh
PS:这里要注意一点,namesecondary里和data里的clusterID值一样;name目录指的是hdfs-site.xml中dfs.name.dir代表的目录,这里是tmp/hdfs/name,同理data目录;因为没有配置secondary目录,所以采用的是默认的配置,所以namesecondary指的是tmp/dfs/namesecondary