本文介绍写入HDFS出现无法close文件的异常的解决方案。

具体报错

java.io.IOException: Unable to close file because the last block xxx:xxx does not have enough number of replicas.

问题原因

一般是由于DataNode写入负载过大引起的,数据块不能及时上报。

解决方案

建议按照以下方式排查解决:
  • 查看HDFS配置
    查看hdfs-site.xml中dfs.client.block.write.locateFollowingBlock.retries(写入块后尝试关闭的次数)参数的配置。默认为5次(30秒),推荐设置为8次(2分钟),负载高的集群可以视情况继续调大。
    说明 调大dfs.client.block.write.locateFollowingBlock.retries参数值,在节点繁忙时会延长文件close的等待时间,正常写入不受影响。
  • 确认集群中是否是只有少量DataNode节点,大量task节点的情况。如果大量并发提交作业,会有大量JAR文件需要上传,可能会导致DataNode瞬时压力大,可以继续调大dfs.client.block.write.locateFollowingBlock.retries参数值或者增加DataNode数量。
    说明 调大dfs.client.block.write.locateFollowingBlock.retries参数值,在节点繁忙时会延长文件close的等待时间,正常写入不受影响。
  • 确认集群中是否有大量消耗DataNode的作业。例如Flink Checkpoint会大量创建和删除小文件,引起DataNode负载过大。此类场景可以把Flink运行在独立的集群上,Checkpoint会使用独立的HDFS,或者使用OSS/OSS-HDFS Connector优化Checkpoint。