记一次HDFS原数据和本地block数据不一致故障的解决
问题描述
7月4日上班之后,发现三个节点磁盘均已达到100%,各种服务均异常,包含HDFS服务(HDFS已进入安全模式),yarn服务等,CDH服务也已挂掉(无法正常重启等)。
处理过程
- HDFS在安全模式,查证之后发现是/user/hive/warehouse/transn_dws.db/.hive-staging_hive_2024-07-04_02-56-24_080_5217892536398673273-78 。 hive计算的临时文件导致了集群打满,观察这个文件占用了三节点2.5T的磁盘。但是由于是安全模式,导致不能进行删除。
- 简单删除了一下除HDFS之外的其他文件,磁盘清理之后,尝试重新拉起其他服务,CDH服务拉起正常。中途由于服务器长时间未进行重启未释放的资源过多,进行了三台节点的重启。
- 重启之后,观察磁盘缺少了data2节点,未进行挂载导致,但是可以正常访问。由于对运维方面知识不太懂,未放在心上,随即拉起服务,使用hdfs dfsadmin -safemode leave命令将HDFS离开安全模式,此时缺块将近1/3。由于仍有大量服务异常,考虑是存储未降下来导致,随机赶紧对dws层的中间文件进行了rm,rm之后对其他服务进行了重启,服务也恢复正常,但yarn服务提示如下异常信息
The health test result for NODE_MANAGER_HEALTH_CHECKER has become bad: The ResourceManager considers this NodeManager unhealthy and will not use it.NodeManager health report: ' 1/1 log-dirs have errors: [ /data2/hadoop_log/hadoop-yarn/container-logs : Directory is not writable: /data2/hadoop_log/hadoop-yarn/container-logs ] '.
考虑到data2盘在df -h时不现实,考虑到无法识别硬盘的原因,随即通知运维进行了重新挂载 mount /dev/vdc1 /data2,重新挂载后发现三个节点的data2盘的空间仍然是98%以上,考虑在删除中间文件时data2盘未挂载,导致未将其删除。
- 挂载data2盘之后,使用CDH对服务进行了重启,此时Hadoop服务均正常了,剩下一个data2盘满的问题有待解决。
- 由于data2盘基本只有hdfs数据,而hdfs数据又无法通过手动删除本地的block数据来释放空间,此时陷入一种原数据已删除,而本地block还存在的困境中。
- 随即使用 hdfs fsck命令查看有没有什么block块异常,但是命令返回异常的快有点多,大部分都是副本缺失问题,没有什么实际作用。在网上搜索发现,可以通过fsimage文件恢复原数据,并替换掉fsimage文件达到恢复的效果,考虑再三觉得风险太高。
- 突然想到通过edit_log能否找到删除的具体block块信息,随即在活跃的nn上下载对应时间段的edit_log,使用hdfs oev -i edits_0000000000741929596-0000000000741929637 -o /tmp/www/edit_log/edits_0000000000741929596-0000000000741929637.xml,命令将二进制edit_log文件解析成xml文件。
edit_log示例
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>741929942</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/data/bigdata/tools/data/tmp/.cloudera_health_monitoring_canary_files/.canary_file_2024_07_04-11_18_23.45daa08d197f3022</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1720063104127</MTIME>
<ATIME>1720063104064</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME/>
<CLIENT_MACHINE/>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1149438373</BLOCK_ID>
<NUM_BYTES>56</NUM_BYTES>
<GENSTAMP>75698362</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>hdfs</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>438</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
- 通过grep等linux命令查到删除的文件对应的block块信息所在,此时已经获得删除文件对应的block_id信息。使用shell脚本查到该批次block_id对应的本地文件位置,对本地文件进行mv,在执行该命令之后,跑了一天etl任务发现无异常,随即将该批次block文件删除,故障得以解决。
故障收获
- 之前未处理过相关故障,未解析过edit_log或者fsimage文件。
hdfs oev -i edits_0000000000741929596-0000000000741929637 -o /tmp/www/edit_log/edits_0000000000741929596-0000000000741929637.xml ##解析edit_log
hdfs oiv -p XML -i /path/to/fsimage -o /output/directory ## 解析fsimage文件
- 使用hdfs fsck 命令查找异常block。
- Edit_log每次会记录删除的HDFS文件对应的本地block块的ID信息。
- HDFS的安全模式尽量不要自己手动离开。。一定是有异常。