问题现象
公司Hadoop集群需要进行扩容,为了使各节点数据均衡需要执行balance操作,在HDFS客户端启动了一个Balance进程,因为某些原因把该进程异常停止了,再次执行Balance操作,操作会失败报错:hdfs balance java.io.IOException: Another Balancer is running.. Exiting
基本原理
HDFS在运行Balancer的时候,会将运行Balancer的主机名写入到balancer.id这个文件里面,通过这个Mark File来检测Balancer是否运行,该文件存放在HDFS上的/system目录下。
通常,HDFS执行Balance操作结束后,会自动释放“/system/balancer.id”文件,可再次正常执行Balance。
但在上述场景中,由于第一次的Balance操作是被异常停止的,所以第二次进行Balance操作时,“/system/balancer.id”文件仍然存在,则会触发append /system/balancer.id 操作,进而导致Balance操作失败。
如果“/system/balancer.id”文件的释放时间超过了软租期60s,则第二次执行Balance操作的客户端的append操作会抢占租约,此时最后一个block处于under construction或者under recovery状态,会触发block的恢复操作,那么“/system/balancer.id”文件必须等待block恢复完成才能关闭,所以此次append操作失败。
append /system/balancer.id操作失败后,会向客户端抛出RecoveryInProgressException异常
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.protocol.RecoveryInProgressException): Failed to APPEND_FILE /system/balancer.id for DFSClient because lease recovery is in progress. Try again later.
如果该文件的释放时间没有超过默认设置60s,原有客户端会继续持有该租约,则会抛出AlreadyBeingCreatedException异常,实际上向客户端返回的是null,导致客户端出现如下异常:
java.io.IOException: Cannot create any NameNode Connectors.. Exiting...
解决方法
方法一
执行第二次Balance操作之前删除“/system/balancer.id”文件。
使用命令:hdfs dfs -cat /system/balancer.id ,查看/system目录下的balancer.id文件内容,如果有内容则
删除balancer.id这个文件,重新执行Balancer命令,可以正常执行数据均衡操作
如果没有balancer.id这个文件,这是Hadoop的一个已知bug:https://issues.apache.org/jira/browse/HDFS-8897
修改当前执行命令节点core_site.xml 的配置fs.defaultFS,去掉最后的 /
-------修改前
fs.defaultFS hdfs://bigdata/
-------修改后
fs.defaultFS hdfs://bigdata
再次执行 hdfs balancer
./sbin/start-balancer.sh -threshold 5
方法二
等待硬租期超过1小时后,原有客户端释放租约,再执行Balance操作
- 本文固定链接: http://www.jiagou.cc/1561/
- 转载请注明: 摘星怪 于 架构迷 发表