最近在帮公司下线离线计算集群的机器,逐台decomiss,下到第四台机器时,cdh告警来了,丢失块大于集群的1%,算了一下集群有400多台,下线一台不应该告警,以为下线步骤有问题,点了中止下线,后来看了下其实步骤是没问题的,由于下线的机器配置比较好,所以确实这台机器上存储了集群1%以上的block,于是终止了datanode的decomission,但是集群还是出现了14个 missing block,按照常理,hdfs上的文件丢失副本只要不是所有副本全丢,过段时间hdfs都会把这些副本从其他节点copy一份,但是这些block随着时间的增加永远不会恢复。
确认了下线步骤没有问题以后,选择原来的datanode继续decomission,但是这一步会一直卡住,不会完成,看了下datanode的日志,确实是在移动数据,但是看节点的io很小,完全达不到正常下线节点时的io。于是这个节点先略过,下线其他节点,发现也出现同样情况,看来继续下线是不行了。
看了一下clouddera社区的一个issue,这好像是cdh的一个bug,上面cdh的官方人员说要把datanode删掉再重新加回来就可以下线了。
于是我把datanode停了,通过cdh监控按到节点上的block全部复制完以后,直接把datanode删除掉了, 没有走正常decomission的流程。弄完之后去hdfs的监控看了下,这个节点直接没了,也不会存在僵死的节点。那就不用再安装回来重新decomission一遍了。用如此的方式,把下线节点的工作都完成之后。来好好查看一下这个问题。
丢块的提示是在hdfs的ui看到的
既然有丢块,那我们就用hdfs fsck /这个命令检查一下,检查的结果竟然没有丢失块,
于是用hdaoop dfsadmin -report 这个命令检查了一下,提示说丢失了14个block,检查的结果是和hdfs界面上的提示是相符的。
既然2个命令的结果不同,那就说明至少有一个是有问题的,所以2个命令都被假设有可能结果是不准确的。
后来通过了解还有一种可能就是文件在被写入的过程中client异常挂掉了,导致租约没有释放,写入没有正常关闭,也有可能造成块无法使用。
参考https://www.cnblogs.com/cssdongl/p/6700512.html
如果这种情况,可以通过hdfs debug recoverLease -path <path-of-the-file> -retries <retry times> 可以恢复文件租约。
但是我们只知道有block有问题,不知道这些块属于哪些文件,怎么验证我们的猜想呢
通过命令 hdfs fsck / -openforwrite |grep -i openforwrite |awk ‘{print $1}‘,把当前正在写入的文件找出来,写个循环脚本,对里面的文件进行恢复租约,
就可以对所有被正在写入的文件去恢复租约,脚本运行完之后,果然这些block missing消失了。
原文地址:https://blog.51cto.com/xiaolanlan/2472323