Cannot obtain block length for LocatedBlock故障分析与解决

在执行hive任务的时候经常会遇到如下错误:

Caused by: java.io.IOException: Cannot obtain block length for LocatedBlock{BP-739651031-192.168.1.50-1452872943245:blk_1329315607_256707953; getBlockSize()=6604762; corrupt=false; offset=0; locs=[192.168.1.55:50010, 192.168.1.56:50010, 192.168.1.53:50010, 192.168.1.71:50010]; storageIDs=[DS-52f0d1de-8124-4ce1-a452-028474f3beee, DS-be33d88c-3d30-4b5f-816c-e7e8344fd573, DS-3d2fd42f-912b-4805-b7a5-e05f99caa6ff, DS-6b4a5d88-d23e-4348-a6e0-7869cef21277]; storageTypes=[DISK, DISK, DISK, DISK]}

 

上层任务执行失败,导致后续任务积压,因此必须解决该问题。

解决方法:
1.首先使用fsck检查一下
hdfs fsck /
当然也可以指定具体的hdfs路径。检查完打印结果没发现任何异常,没发现任何损坏或CORRUPT的block,继续排查。
2.加上其他参数细查
hdfs fsck / -openforwrite
这次检查出来不少文件打印显示都是 openforwrite状态,而且Status为CORRUPT。经测试发现,这些文件无法get和cat。所以这里的“ Cannot obtain block length for LocatedBlock ”结合字面意思讲应该是当前有文件处于写入状态尚未关闭,无法与对应的datanode通信来成功标识其block长度。

那么分析其产生的可能性,举例子如下 :

    Flume客户端写入hdfs文件时的网络连接被不正常的关闭了 ;
    Flume客户端写入hdfs失败了,而且其replication副本也丢失了 。

总结一下就是Flume写入的hdfs文件由于什么原因没有被正常close,状态不一致随后无法正常访问。
-

 

上图中主要存在两个问题:一是块丢失;二是副本数量为2(正常情况下为3)。针对此类问题,最好的方法是重新上传原日志,分两种情况解决:
1.原日志存在
显然,找到原日志,重新上传。

2.原日志不存在
原日志不存在时,针对副本数量缺失的情况,可以先get到本地,删除HDFS上相应的文件,然后重新put到HDFS。针对块丢失的情况,依然如此。只不过是在get的过程中坏块无法get到本地,只能get正常的块。所有get到本地的块均正常,然后再put到HDFS,问题解决(此方法适用于有坏块或MISSING block的情况)。

如要删除坏块,使用 hdfs fsck -delete命令。

 

 

 

 

副篇

 

查询资料发现可以用恢复租约的方法解决,不过我还没尝试过,粘贴下链接,可以了解下。https://www.cnblogs.com/cssdongl/p/6700512.html

这几天想cat一下某天的HDFS文件内容的时候突然报Cannot obtain block length for LocatedBlock异常,get也一样,这样无法访问hdfs文件的问题必须解决,Mark一下问题背景和解决过程

一.问题背景

问题产生的原因可能是由于前几日Hadoop集群维护的时候,基础运维组操作不当,先关闭的Hadoop集群,然后才关闭的Flume agent导致的hdfs文件写入后状态不一致。排查和解决过程如下.

二.解决过程

1.既然是hdfs文件出问题,用fsck检查一下吧

hdfs fsck /

当然你可以具体到指定的hdfs路径,检查完打印结果没有发现任何异常,没有发现损坏或者Corrupt的block,继续排查

2.那么加上其他参数细查

hdfs fsck / –openforwrite

ok,这次检查出来不少文件打印显示都是 openforwrite状态,而且我测试相应文件确实不能读取,这很不正常不是吗?Flume已经写过的hdfs文件居然还处于openforwrite状态,而且无法cat和get

所以这里的”Cannot obtain block length for LocatedBlock”结合字面意思讲应该是当前有文件处于写入状态尚未关闭,无法与对应的datanode通信来成功标识其block长度.

那么分析其产生的可能性,举栗子如下

1>Flume客户端写入hdfs文件时的网络连接被不正常的关闭了

或者

2>Flume客户端写入hdfs失败了,而且其replication副本也丢失了

我这里应该属于第一种,总结一下就是Flume写入的hdfs文件由于什么原因没有被正常close,状态不一致随后无法正常访问.继续排查

3.推断:HDFS文件租约未释放

可以参考这篇文章来了解HDFS租约机制 http://www.cnblogs.com/cssdongl/p/6699919.html

了解过HDFS租约后我们知道,客户端在每次读写HDFS文件的时候获取租约对文件进行读写,文件读取完毕了,然后再释放此租约.文件状态就是关闭的了。

但是结合当前场景由于先关闭的hadoop集群,后关闭的Flume sink hdfs,那么hadoop集群都关了,Flume还在对hdfs文件写入,那么租约最后释放了吗?答案是肯定没释放.

4.恢复租约

对于这些状态损坏的文件来讲,rm掉的话是很暴力的做法,万一上游对应日期的数据已经没有rention呢?所以,既然没有释放租约,那么恢复租约close掉文件就是了,如下命令

hdfs debug recoverLease -path <path-of-the-file> -retries <retry times>

请将<path-of-the-file>修改成你需要恢复的租约状态不一致的hdfs文件的具体路径,如果要恢复的很多,可以写个自动化脚本来找出需要恢复的所有文件然后统一恢复租约.

ok,执行完命令后再次cat对应hdfs文件已无异常,顺利显示内容,问题解决.

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值