定位block块位置

  • 异常

Caused by: org.apache.hadoop.hdfs.CannotObtainBlockLengthException: Cannot obtain block length for LocatedBlock{BP-215372827-172.23.30.41-1598540639502:blk_1112686982_38963124; getBlockSize()=101167104; corrupt=false; offset=0; locs=[DatanodeInfoWithStorage[172.23.30.49:50010,DS-c7b04aae-f19a-40c1-aee1-34da52e730f6,DISK], DatanodeInfoWithStorage[172.23.30.73:50010,DS-12bf675c-b13e-4437-bd9d-0fc4acb200fe,DISK]]}
at org.apache.hadoop.hdfs.DFSInputStream.readBlockLength(DFSInputStream.java:360)
at org.apache.hadoop.hdfs.DFSInputStream.fetchLocatedBlocksAndGetLastBlockLength(DFSInputStream.java:267)
at org.apache.hadoop.hdfs.DFSInputStream.openInfo(DFSInputStream.java:198)
at org.apache.hadoop.hdfs.DFSInputStream.(DFSInputStream.java:182)
at org.apache.hadoop.hdfs.DFSClient.openInternal(DFSClient.java:1042)
at org.apache.hadoop.hdfs.DFSClient.open(DFSClient.java:1005)
at org.apache.hadoop.hdfs.DistributedFileSystem$4.doCall(DistributedFileSystem.java:320)
at org.apache.hadoop.hdfs.DistributedFileSystem$4.doCall(DistributedFileSystem.java:316)
at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
at org.apache.hadoop.hdfs.DistributedFileSystem.open(DistributedFileSystem.java:328)
at org.apache.hadoop.fs.FileSystem.open(FileSystem.java:899)
at org.apache.hadoop.mapred.LineRecordReader.(LineRecordReader.java:109)
at org.apache.hadoop.mapred.TextInputFormat.getRecordReader(TextInputFormat.java:67)
at org.apache.hadoop.hive.ql.io.HiveInputFormat.getRecordReader(HiveInputFormat.java:418)
… 22 more
]], Vertex did not succeed due to OWN_TASK_FAILURE, failedTasks:1 killedTasks:0, Vertex vertex_1649227221040_0263_1_00 [Map 1] killed/failed due to:OWN_TASK_FAILURE]Vertex killed, vertexName=Reducer 2, vertexId=vertex_1649227221040_0263_1_01, diagnostics=[Vertex received Kill while in RUNNING state., Vertex did not succeed due to OTHER_VERTEX_FAILURE, failedTasks:0 killedTasks:51, Vertex vertex_1649227221040_0263_1_01 [Reducer 2] killed/failed due to:OTHER_VERTEX_FAILURE]DAG did not succeed due to VERTEX_FAILURE. failedVertices:1 killedVertices:1 (state=08S01,code=2)
Closing: 0: jdbc:hive2://PM-HAD30-42:10000
[ERROR] countly埋点数据dwd同步失败!
2022-04-07 13:55:57 [com.xxl.job.core.thread.JobThread]-[run]-[124]-[Thread-10108]
----------- xxl-job job execute end(finish) -----------
----------- ReturnT:ReturnT [code=500, msg=script exit value(1) is failed, content=null]

以下内容为转载:
另外需要交待一下背景,下午发生2个datanode机器同时宕机的问题,我们是有2副本的数据的,因此当2个datanode同时失效,一定会有一定比例的块丢失,在这两个datanode恢复一个之前,一定又有hdfs的客户端报错Missing Block。

本文这个问题更加特殊,在这个任务失败前,2个宕机节点都已经恢复了,不存在missing block。

所以这个情况给了我们一个非常重要的警示,即使不存在missing block,不代表hdfs的数据状态就100%正常的,而且hdfs不会给出提示,目前只有客户端读取这些数据的时候才能发现,不可不谓一个重大的隐患。

在datanode恢复以后,没有missing block依然有状态不正常的数据,我们可以很自然的想到,数据没有丢,但是正在write过程中的数据,由于datanode强行的关闭,导致namenode对block的状态了解的不正常。

涉及到write的过程,我们很自然的可以了解到写锁,在hdfs里叫租约机制。 这个时候我们的一个猜想就是这个block是存在的,但是因为datanode的非正常关闭导致namenode对于这个block的认知依然是它还在openforwrite状态。

我们知道Hadoop提供了关于租约机制的修复工具,如下

hdfs debug recoverLease -path [path] 需要指定文件路径。

文件路径怎么来?

通过异常日志,我们可以看到blk_XXXXXXXX 这个就是blockId

通过 hdfs fsck -showprogress -blockId blk_XXXXXXX 我们可以了解到这个block对应的目录是什么
在这里插入图片描述
使用

hdfs fsck -showprogress -blockId blk_XXXXXXX

的时候,blk_1112686982_38963124,只需要写到blk_1112686982就行了,否则找不到

同时还可以查看到,这个block的信息并没有展现出block的

Block replica on datanode/rack: PM-HAD30-74/default-rack is HEALTHY

我们执行如下命令:

hdfs debug recoverLease -path /warehouse/tablespace/managed/hive/oa_statistics.db/countly_oa_log_ods/data_date=2022-04-06/part_20220406_14.1649224800417 -retries 10

再次 hdfs fsck -showprogress -blockId blk_XXXXXXX
在这里插入图片描述
会看到block的健康信息,重跑任务,问题解决。

问题简单复盘:

我们可以查看

org.apache.hadoop.hdfs.DFSInputStream#readBlockLength(LocatedBlock locatedblock) 这个方法的代码。

这个就是抛出CannotObtainBlockLengthException的代码。

很直观的可以看到,入参LocatedBlock 是带有block位置信息的block对象,因此没有block的位置信息,最终会抛异常,为什么没有位置信息? 因为hdfs认为这个block还在读写的过程中。

那么lease recovery的作用是什么呢? 无非是以某种策略,让hdfs接受当前block情况,释放租约,释放“锁”,达到一个hdfs中block的最终状态。 类似于我们通过IO流写文件最后需要 close()来释放系统资源。

达到这个状态的block,就相当于释放了“写锁”,自然可以读。

结论:

遇到这个问题怎么办?

第一步 定位问题block是哪个文件

hdfs fsck -showprogress -blockId blk_XXXXXXXX

第二部 修复租约,路径可以通过上一步获取到

hdfs debug recoverLease -path “文件在hdfs的路径”

原文链接:https://blog.csdn.net/trmplarguard/article/details/109622760

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值