CDH集群下DataNode与NameNode通信失败问题
问题报错:
Datanode denied communication with namenode because the host is not in the include-list
2022-05-17 17:27:17,386 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool BP-466489028-172.16.16.4-1652762404340 (Datanode Uuid cbd2ce09-33b5-452d-901f-93a05f39ccc4) service to master01/172.16.16.4:8022 Datanode denied communication with namenode because the host is not in the include-list: DatanodeRegistration(172.16.16.5:9866, datanodeUuid=cbd2ce09-33b5-452d-901f-93a05f39ccc4, infoPort=9864, infoSecurePort=0, ipcPort=9867, storageInfo=lv=-57;cid=cluster20;nsid=830204877;c=1652762404340)
at org.apache.hadoop.hdfs.server.blockmanagement.DatanodeManager.registerDatanode(DatanodeManager.java:1035)
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.registerDatanode(BlockManager.java:2315)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.registerDatanode(FSNamesystem.java:3777)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.registerDatanode(NameNodeRpcServer.java:1467)
at org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolServerSideTranslatorPB.registerDatanode(DatanodeProtocolServerSideTranslatorPB.java:101)
at org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos$DatanodeProtocolService$2.callBlockingMethod(DatanodeProtocolProtos.java:31658)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:523)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:991)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:869)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:815)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2675)
在看之前,首先确保你已经自行排除以下问题
1. 服务器之间不能通信
2. NameNode处于SafeMode
先分析,进入 /var/run/cloudera-scm-agent/process/文件夹下,找到最新的NameNode启动运行记录,我这里是99-hdfs-NAMENODE(对应数字最大的就是最新的运行文件夹)
[root@master01 ~]# cd /var/run/cloudera-scm-agent/process/
[root@master01 process]# ll
......
drwxr-x--x 3 hdfs hdfs 560 May 17 15:18 99-hdfs-NAMENODE
......
[root@master01 99-hdfs-NAMENODE]# cat dfs_all_hosts.txt
{"hostName":"172.16.16.4","port":9866,"adminState":"NORMAL"}
{"hostName":"172.16.16.5","port":9866,"adminState":"NORMAL"}
{"hostName":"172.16.16.6","port":9866,"adminState":"NORMAL"}
[root@master01 99-hdfs-NAMENODE]#
问题1: 无法通信的DataNode所在的机器ip没有出现在 dfs_all_hosts.txt 文件中
解决方案:
-
将机器ip按格式加入到 dfs_all_hosts.txt 文件中。(一定是最新的NameNode运行的文件夹中的文件)
-
进入NameNode所在的机器上执行 hdfs dfsadmin -refreshNodes
## 注意下面的‘-’,有可能因为浏览器的原因导致编码出问题,自己敲一下命令 [root@master01 99-hdfs-NAMENODE]# hdfs dfsadmin -refreshNodes ## 如果出现权限问题,执行如下 [root@master01 99-hdfs-NAMENODE]# sudo -u hdfs hdfs dfsadmin -refreshNodes ## 如果登录不了NameNode所在的机器,执行如下 [root@master01 99-hdfs-NAMENODE]# sudo -u hdfs hdfs dfsadmin -fs hdfs://NameNode机器IP:8020 -refreshNodes
-
重新平衡
这个方案有缺陷,就是不能重启HDFS服务,重启之后之前不能通信的DataNode仍然不能通信
问题2: CDH集群部署集群时,每台机器自己的主机名对应的ip是内网ip,导致集群中每台机器的ip可能一致,CDH在加载ip时是从每台主机处加载,使用的并不是/etc/hosts中配置的ip,所以遇到相似的ip会自动排除(这是我猜的,未证实)。
解决方案:
-
首先修改机器的内网ip
-
重启相应服务
-
按照问题1的解决方案解决
这个方案可能会导致hdfs重启后之前无法访问的DataNode仍然无法访问
问题3: 无法通信的DataNode所在的机器ip出现在 dfs_all_hosts.txt 文件中
解决方案: 参照问题1解决方案第二步刷新DataNode
问题4: 问题1的进阶版
描述: 以上的方案都是有缺陷的,就是hdfs不能重启的问题。有没有什么其他的方法呢可以保证我们能够重启hdfs之后DataNode和NameNode之间仍然可以通信呢?方法其实是有的,我们先搞清楚dfs_all_hosts.txt大概是个什么作用,说实话,我找了很久,也没找到这个文件到底是怎么生成的,具体在哪里使用的。但是我们可以根据他的内容去猜测,它里面存储的是DataNode节点的地址,这就很有意思了。不知道大家以前独立部署过hadoop没有,如果配置过,应该会配置过一个文件存储节点(DataNode)的地址,可能叫做slaves或者workers。那么这里的dfs_all_host.txt是不是也是这个作用呢?我们直接查看同样文件夹下的hdfs-site.xml文件,发现dfs.hosts的参数中就使用到了dfs_all_hosts.txt。dfs.hosts参数就是用来指明白名单的,如果不配置就是所有机器,配置了之后就只能与配置的机器通信了。这下我们知道了dfs_all_hosts.txt差不多就是slaves/workers节点的意思。那我们就好做了。我们在NameNode所在的机器新建一个文件就好了,然后配置dfs.hosts指向该文件就完了。操作如下:
解决方案:
- 登录到NameNode所在的服务器,创建一个文件allow-list,加入DataNode所在的机器名称
[root@master01 home]# vi allow-list
master01
slave01
slave02
[root@master01 home]#
- 登录CDH,进入HDFS配置界面,配置dfs.hosts
- 重启hdfs服务
- 重新刷新节点,问题1解决方案第二步
- CDH重新平衡服务即可
总结: 问题4的解决方案应该可以解决很多问题了,但是我自己最后还是有一个疑问,那就是dfs_all_hosts.txt到底是怎么生成的,难受啊,如果有小伙伴知道的话,欢迎你评论告诉我一下了。当然如果有小伙伴用以上方法仍然无法解决NameNode和DataNode通信的问题,也欢迎你在评论区提出来我们一起解决。