Hadoop DataNode reconfig Version Mismatch 异常分析


1. 背景

在 Hadoop 3.1 中执行 DataNode 动态刷新配置时,使用了下面的命令:

hdfs dfsadmin -reconfig datanode xx.88:50010 properties

命令执行后,DataNode 日志中出现如下异常:

ERROR datanode.DataNode (DataXceiver.java:run(321)) - xx:50010:DataXceiver error processing unknown operation  src: /xx.28:52724 dst: /xx.28:50010
java.io.IOException: Version Mismatch (Expected: 28, Received: 26738 )
        at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.readOp(Receiver.java:73)
        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:269)
        at java.lang.Thread.run(Thread.java:748)

从日志看,报错位置在 DataXceiver,不是 NameNode,也不是 dfsadmin 客户端本身。

这个问题的原因不是 Hadoop 版本不一致,也不是 DataNode 真的不能 reconfig,而是命令中使用了错误的 DataNode 端口。

2. 问题现象

异常中有几个关键信息:

dst: /xx.28:50010
DataXceiver error processing unknown operation
Version Mismatch (Expected: 28, Received: 26738 )

其中 50010 是 Hadoop 2.x 中常见的 DataNode 数据传输端口,也就是 dfs.datanode.address 对应的端口。这个端口主要用于 HDFS 客户端和 DataNode 之间读写 block 数据。

但是 hdfs dfsadmin -reconfig datanode 不是读写 block 数据,它是一个管理命令,需要访问 DataNode 的 IPC/RPC 端口。

这两个端口不是一回事。

3. 原因分析

3.1 -reconfig 需要连接的是 IPC 端口

Hadoop 3.1.1 官方 HDFS Commands Guide 中对 -reconfig 的参数说明如下:

hdfs dfsadmin [-reconfig <namenode|datanode> <host:ipc_port> <start |status |properties>]

也就是说,第二个参数应该是:

host:ipc_port

这里明确写的是 ipc_port,不是 DataNode 的数据传输端口。

如果要对 DataNode 做动态配置,可以使用:

hdfs dfsadmin -reconfig datanode <datanode_host>:<datanode_ipc_port> properties
hdfs dfsadmin -reconfig datanode <datanode_host>:<datanode_ipc_port> start
hdfs dfsadmin -reconfig datanode <datanode_host>:<datanode_ipc_port> status

3.2 50010 是 DataNode 数据传输端口

在 Hadoop 2.x 或者一些兼容旧端口的发行版中,常见端口如下:

配置项 端口 作用
dfs.datanode.address 50010 DataNode 数据传输端口,读写 block 使用
dfs.datanode.ipc.address 50020 DataNode IPC/RPC 管理端口
dfs.datanode.http.address 50075 DataNode Web 页面端口

而 Hadoop 3.x 默认端口已经调整,常见默认值如下:

配置项 Hadoop 3.x 默认端口 作用
dfs.datanode.address 9866 DataNode 数据传输端口
dfs.datanode.ipc.address 9867 DataNode IPC/RPC 管理端口
dfs.datanode.http.address 9864 DataNode Web 页面端口

所以在 Hadoop 3.1 中,如果没有保留旧端口配置,正确的 reconfig 端口一般应该是 9867

如果集群为了兼容旧版本保留了旧端口,那么正确的 reconfig 端口一般是 50020,而不是 50010

3.3 为什么会报 Version Mismatch

DataNode 的 50010 端口运行的是 HDFS DataTransferProtocol。这个协议用于处理 block 读写请求,DataXceiver 会按照数据传输协议读取客户端发来的内容。

但是 hdfs dfsadmin -reconfig 发出的请求是 Hadoop RPC 请求。

也就是说:

RPC 请求 -> 发到了 DataTransfer 端口

DataXceiver 收到后,会尝试按照 DataTransferProtocol 读取协议版本。它期望读取到的数据传输协议版本是 28,但实际读到的是 26738,于是报:

Version Mismatch (Expected: 28, Received: 26738 )

这个 26738 也很有意思。26738 转成十六进制是:

0x6872

0x68 0x72 对应 ASCII 字符是:

h r

Hadoop RPC 连接头通常以 hrpc 开始。也就是说,DataXceiver 在数据传输端口上读到了 RPC 请求头的前两个字节,于是把它当成 DataTransferProtocol 的版本号,最后就出现了这个看起来像“版本不匹配”的错误。

所以这个异常表面上是版本不匹配,本质上是协议不匹配。

4. 解决方式

4.1 查询当前 DataNode IPC 端口

不要直接使用 hdfs dfsadmin -report 中看到的 DataNode 地址作为 reconfig 地址,因为 report 中显示的 Name: host:port 通常是 DataNode 的数据传输地址。

更稳妥的方式是直接查看配置:

hdfs getconf -confKey dfs.datanode.ipc.address

如果输出类似:

0.0.0.0:9867

则说明 DataNode IPC 端口是 9867

如果输出类似:

0.0.0.0:50020

则说明集群使用的是旧端口配置,DataNode IPC 端口是 50020

也可以在 DataNode 节点上查看监听端口:

ss -lntp | grep -E '50010|50020|9866|9867'

正常情况下可以看到 DataNode 同时监听数据传输端口和 IPC 端口。

4.2 使用正确端口执行 reconfig

如果集群使用 Hadoop 3.x 默认端口:

hdfs dfsadmin -reconfig datanode xx.88:9867 properties

如果集群保留了 Hadoop 2.x 常见旧端口:

hdfs dfsadmin -reconfig datanode xx.88:50020 properties

如果要真正触发配置刷新,可以执行:

hdfs dfsadmin -reconfig datanode xx.88:50020 start

然后查看状态:

hdfs dfsadmin -reconfig datanode xx.88:50020 status

实际端口以当前集群的 dfs.datanode.ipc.address 为准。

4.3 先用 getDatanodeInfo 验证端口是否正确

在执行 reconfig 之前,可以先用下面的命令测试 DataNode IPC 端口是否可用:

hdfs dfsadmin -getDatanodeInfo xx.88:50020

如果端口正确,应该能返回 DataNode 信息。

如果仍然把端口写成 50010,就可能继续在 DataNode 日志中看到 DataXceiver 的协议解析异常。

5. 排查思路总结

这个问题可以按照下面的顺序排查:

  1. 先确认命令中使用的是不是 DataNode IPC 端口。
  2. 查看 dfs.datanode.ipc.address 的实际配置。
  3. 区分 dfs.datanode.addressdfs.datanode.ipc.address
  4. 不要把 dfsadmin -report 里显示的 DataNode 数据传输端口直接拿来执行 reconfig
  5. 使用 getDatanodeInfo 验证 IPC 端口可用后,再执行 reconfig

排查这类问题时,关键是先判断日志来自哪个服务端线程。

这次日志来自:

DataXceiver

DataXceiver 处理的是 DataNode 数据传输协议。如果一个管理命令触发了 DataXceiverVersion Mismatch,就应该优先怀疑命令连接到了错误端口,而不是优先怀疑 Hadoop jar 包版本不一致。

6. 总结

这次问题的根因是:

hdfs dfsadmin -reconfig datanode 使用了 DataNode 数据传输端口 50010,
但该命令要求使用 DataNode IPC/RPC 端口。

正确命令应该类似:

# Hadoop 3.x 默认端口
hdfs dfsadmin -reconfig datanode xx.88:9867 properties

# 如果集群保留旧端口配置
hdfs dfsadmin -reconfig datanode xx.88:50020 properties

Version Mismatch (Expected: 28, Received: 26738) 并不一定表示 Hadoop 版本真的不一致。在这个场景下,它表示 RPC 协议请求被发送到了 DataTransferProtocol 端口,DataNode 按错误协议解析了请求。

简单来说:

50010 / 9866 是 DataNode 数据传输端口
50020 / 9867 是 DataNode IPC 管理端口
reconfig 要使用 IPC 管理端口

文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
  目录