更新时间:2022-02-22 GMT+08:00

DataNode状态正常,但无法正常上报数据块

问题

DataNode正常,但无法正常上报数据块,导致存在的数据块无法使用。

回答

当某个数据目录中的数据块数量超过4倍的数据块限定值(1M)时,可能会出现该错误。DataNode会产生相应的错误日志记录,如下所示:

2015-11-05 10:26:32,936 | ERROR | DataNode:[[[DISK]file:/srv/BigData/hadoop/data1/dn/]] heartbeating to 
vm-210/10.91.8.210:8020 | Exception in BPOfferService for Block pool BP-805114975-10.91.8.210-1446519981645 
(Datanode Uuid bcada350-0231-413b-bac0-8c65e906c1bb) service to vm-210/10.91.8.210:8020 | BPServiceActor.java:824 
java.lang.IllegalStateException:com.google.protobuf.InvalidProtocolBufferException:Protocol message was too large.May 
be malicious.Use CodedInputStream.setSizeLimit() to increase the size limit. at org.apache.hadoop.hdfs.protocol.BlockListAsLongs$BufferDecoder$1.next(BlockListAsLongs.java:369) 
at org.apache.hadoop.hdfs.protocol.BlockListAsLongs$BufferDecoder$1.next(BlockListAsLongs.java:347) at org.apache.hadoop.hdfs.
protocol.BlockListAsLongs$BufferDecoder.getBlockListAsLongs(BlockListAsLongs.java:325) at org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolClientSideTranslatorPB.
blockReport(DatanodeProtocolClientSideTranslatorPB.java:190) at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.blockReport(BPServiceActor.java:473) 
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.offerService(BPServiceActor.java:685) at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:822) 
at java.lang.Thread.run(Thread.java:745) Caused by:com.google.protobuf.InvalidProtocolBufferException:Protocol message was too large.May be malicious.Use CodedInputStream.setSizeLimit() 
to increase the size limit. at com.google.protobuf.InvalidProtocolBufferException.sizeLimitExceeded(InvalidProtocolBufferException.java:110) at com.google.protobuf.CodedInputStream.refillBuffer(CodedInputStream.java:755) 
at com.google.protobuf.CodedInputStream.readRawByte(CodedInputStream.java:769) at com.google.protobuf.CodedInputStream.readRawVarint64(CodedInputStream.java:462) at com.google.protobuf.
CodedInputStream.readSInt64(CodedInputStream.java:363) at org.apache.hadoop.hdfs.protocol.BlockListAsLongs$BufferDecoder$1.next(BlockListAsLongs.java:363)

如今,数据目录中数据块的数量会显示为Metric。用户可以通过以下URL对该值进行监视http://<datanode-ip>:<http-port>/jmx,如果该值超过4倍的限定值(4*1M),建议用户配置多个驱动器并重新启动HDFS。

恢复步骤:

  1. 在DataNode上配置多个数据目录。

    示例:在原先只配置了/data1/datadir的位置

    <property> <name>dfs.datanode.data.dir</name> <value>/data1/datadir</value> </property>

    按照如下内容进行配置。

    <property> <name>dfs.datanode.data.dir</name> <value>/data1/datadir/,/data2/datadir,/data3/datadir</value> </property>

    建议多个数据目录应该配置到多个磁盘中,否则所有的数据都将写入同一个磁盘,对性能有很大的影响。

  2. 重新启动HDFS。
  3. 按照如下方法将数据移动至新的数据目录。

    mv /data1/datadir/current/finalized/subdir1 /data2/datadir/current/finalized/subdir1

  4. 重新启动HDFS。