目录
背景:
测试环境今天有人反馈有DataNode节点挂掉有部分block不能用的问题,看了下确实active的NN页面显示有52336个坏块,且看datanode节点列表有个节点是Dead状态,不过仔细一看发现stanby的NN的页面里该DataNode是正常的。
所需知识:
坏块:corruptReplicas,损坏的块 在NameNode页面上所表示的损坏块的个数就是corruptReplicas对象的大小。
一个是长度大小不匹配,另一个是版本信息不匹配
![](/qrcode.jpg)
(参考另一篇hdfs数据块分类:https://blog.csdn.net/JacksonKing/article/details/103889607)
从目前两个NN的DataNode列表状态不同看,很有可能就是两个NN保留的数据块信息不对,很有可能是当前的NN的DataNode信息不全导致的。
这个问题大致猜测如下原因:
NNA、NNB、问题节点DataNode(DN1)
- NameNode的节点出现过主备切换,原本active的NNA切换为stanby,NNB为active
- 在选主过程中DN1出现挂掉
- 挂掉后再次重启的DN1不能正常的往当前active的NNB汇报数据块,导致NNB的webUI显示大量的数据块损坏
坏块处理:
网上,坏块大家一般都是采用两种方式处理:
- 删除坏块(hdfs fsck path -delete )
- 移动到/lost+found(hdfs fsck path -move)
看数据是老数据又是测试环境,于是尝试了第一种方式
输出类似的信息
在NN的webUI里过一会刷新发现坏块数据少一个
批量删除坏块
通过以下命令得到
//得到所有坏块信息
hdfs fsck / -list-corruptfileblocks > corruptfileblocks.txt
//去除corruptfileblocks.txt中收尾两行
//得到全部的坏块文件列表toDelete.txt
awk 'BEGIN{IFS='\t'}{print $2}' corruptfileblocks.txt >toDelete.txt
通过上面delete的方式尝试了几次发现可以正常删除,但是执行一部分删除后,发现控制台大量输出其他目录的检测副本是否满足最低副本的信息
/user/z**-**.idx: MISSING 1 blocks of total size 3636 B..
/user/z**-**: CORRUPT blockpool BP-535417423-**-1535976912717 block blk_1091860385
.....
Target Replicas is 3 but found 2 replica(s).
由于信息刷得太快,也忘记先截图保存现场信息
请教了一个大神,说是只有副本不满足最低副本数时才会触发扫描再复制,但是输出的不是我的目标目录就很奇怪了
为了避免误操作,决定放弃删除坏块,看下有没有其他解决方案
回到最开始的猜想,既然两个 NN持有的DataNode信息是不一致的,且stanby的NNA里DN1是正常的,那我重启下当前active的NNB,让其主备切换,是不是就能恢复数据块信息呢?
于是一顿操作猛如虎,事情没那么顺利
- 尝试通过刷新节点列表让datanode主动汇报,发现还是没用(hdfs dfsadmin -refreshNodes)
- 把NN停了,一段时间发现NNA没切换为active
- 查看zkfc进程也还在,再看NNA的zkc进程的日志,发现怎么没及时切换active呢?
020-01-08 16:16:08,571 INFO org.apache.hadoop.ha.NodeFencer: Trying method 1/1: org.apache.hadoop.ha.SshFenceByTcpPort(null)
2020-01-08 16:16:08,875 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Connecting to NNB...
2020-01-08 16:16:08,880 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Connecting to NNB port 22
2020-01-08 16:16:08,978 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Connection established
2020-01-08 16:16:09,493 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Remote version string: SSH-2.0-OpenSSH_5.3
2020-01-08 16:16:09,494 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Local version string: SSH-2.0-JSCH-0.1.42
2020-01-08 16:16:09,500 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
2020-01-08 16:16:09,886 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: aes256-ctr is not available.
2020-01-08 16:16:09,886 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: aes192-ctr is not available.
2020-01-08 16:16:09,886 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: aes256-cbc is not available.
2020-01-08 16:16:09,886 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: aes192-cbc is not available.
2020-01-08 16:16:09,886 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: arcfour256 is not available.
2020-01-08 16:16:09,944 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_KEXINIT sent
2020-01-08 16:16:09,944 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_KEXINIT received
2020-01-08 16:16:09,952 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: kex: server->client aes128-ctr hmac-md5 none
2020-01-08 16:16:09,956 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: kex: client->server aes128-ctr hmac-md5 none
2020-01-08 16:16:10,105 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_KEXDH_INIT sent
2020-01-08 16:16:10,105 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: expecting SSH_MSG_KEXDH_REPLY
2020-01-08 16:16:10,270 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: ssh_rsa_verify: signature true
2020-01-08 16:16:10,273 WARN org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Permanently added 'NNB' (RSA) to the list of known hosts.
2020-01-08 16:16:10,279 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_NEWKEYS sent
2020-01-08 16:16:10,279 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_NEWKEYS received
2020-01-08 16:16:10,294 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_SERVICE_REQUEST sent
2020-01-08 16:16:10,295 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: SSH_MSG_SERVICE_ACCEPT received
2020-01-08 16:16:10,303 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Authentications that can continue: publickey,keyboard-interactive,password
2020-01-08 16:16:10,303 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Next authentication method: publickey
2020-01-08 16:16:10,497 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Authentication succeeded (publickey).
2020-01-08 16:16:10,507 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Connected to NNB
2020-01-08 16:16:10,518 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Looking for process running on port 9001
看了下9001的端口是rpc端口,但是NNB进程是正常的啊,
- 决定重启下NNA的zkfc进程,依然没用,
- 最后再重启一次NNB,发现NNA成功切为active了
再观察两个NN的webUI,发现坏块列表已消失,仔细看了下两个NN的块记录数,发现确实切换为NNA后块数增加了7万多
2542748 files and directories, 1998084 blocks = 4540832 total filesystem object(s).
2617491 files and directories, 1998582 blocks = 4616073 total filesystem object(s).
不过,以后在生产的话,还是提前确认数据块数及变化情况,避免数据丢失的问题
总结:
- 出现坏块时确认坏块是什么原因造成的
- 主备切换时如果DataNode挂掉可能导致坏块产生,但是不一定是真的数据块坏掉了,可能是DataNode没汇报上来
- 可能由于NameNode大量的数据块操作导致RPC阻塞了zkfc进程的主备切换操作,需要重启NN解决
未解决疑问:
- 执行hdfs fsck path -delete 为什么会输出其他目录的副本检测结果?
- 执行hdfs fsck path -delete 会将目录移到到/lost+found吗?照理说-move才会,但是怎么在/lost+found发现了-delete的目录呢?