1.问题描述
hql脚本夜间调度时部分表随机出现了 Unable to close file because the last block does not have enough number of replicas 的报错。 手动重跑后恢复正常。
2.查找原因
通过报错信息可以得知 最后一个block块没有足够的副本而不能关闭文件。 这说明了在某一时刻可能有任务大量读取blocks,耗费了过多的资源。 因此我打开了cm来查看,发现在3点10左右blocks读取过大。
于是开始排查3点10分左右运行的任务(重点排查分区dt存在 between的任务,因为分区跨度大的话读取的blocks也会过多),经过排查发现某个任务跨分区较多,某一时刻瞬间读取了3000多个blocks,最终造成了副本不足。
3.解决办法 (建议使用第一种方法)
1)排查出读取blocks过多的任务,对该任务进行优化调整,缩短读取的时间范围或通过中间表的形式进行查询,尽可能的不要一次读取过多blocks。
2)可以通过调整参数dfs.client.block.write.locateFollowingBlock.retries的值来增加retry的次数,可以将值设置为6(默认5次),那么中间睡眠等待的时间为400ms、800ms、1600ms、3200ms、6400ms、12800ms,也就是说close函数最多要50.8秒才能返回。