Hadoop 3.3.1 → 3.4.1 版本差异与依赖兼容性分析
一、版本基本信息
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| 发布日期 | 2021年6月 | 2024年10月 |
| 中间版本 | - | 经过 3.3.x 系列、3.4.0 |
| 主要变化 | 稳定性增强 | 重大功能升级 |
二、核心组件重大变化
1. AWS SDK 升级(最重要的变化)
| 变化项 | 3.3.1 | 3.4.1 |
| AWS SDK 版本 | SDK V1 | SDK V2 (1.12.720+) |
| S3 Select 支持 | 支持 | 已移除 |
| S3 Express One Zone | 不支持 | 完全支持 |
| FIPS 端点支持 | 有限 | 增强支持 |
关键配置变化:
- 新增
fs.s3a.classloader.isolation 选项
- 新增
fs.s3a.retry.http.5xx.errors 控制重试策略
- 目录标记保留策略从"delete"改为"keep"
2. ABFS (Azure Data Lake) 增强
| 功能 | 3.3.1 | 3.4.1 |
| HTTP 客户端 | 仅 JDK HttpURLConnection | 可选 Apache HttpClient |
| Prefetching | 默认启用 | 默认禁用 |
| Manifest Committer | 非默认 | 默认提交器 |
| 数据缓冲方式 | disk | bytebuffer(默认) |
新增配置:
<property>
<name>fs.azure.networking.library</name>
<value>JDK_HTTP_URL_CONNECTION</value>
<!-- 或 APACHE_HTTP_CLIENT -->
</property>
三、HDFS 新特性
1. 存储与编码
| 特性 | 3.3.1 | 3.4.1 |
| NVDIMM 存储类型 | 无 | 新增支持 |
| SM4 加密 | 无 | 新增支持 |
| 纠删码验证 | 无 | DataNode端验证 |
| 块放置策略 | 标准策略 | AvailableSpaceRackFaultTolerant |
2. DataNode 增强
动态重配置:支持运行时重新配置多个参数:
- 块报告间隔 (
dfs.blockreport.intervalMsec)
- 缓存报告参数
- 慢盘/慢节点参数
- 传输带宽限制
性能优化:
- 细粒度锁机制(卷级别锁)
- 排除慢磁盘的卷选择
- 慢节点检测和指标
3. RBF (Router-Based Federation) 增强
| 特性 | 3.3.1 | 3.4.1 |
| Federation Rename | 基础支持 | 跨命名空间重命名 |
| Observer 支持 | 无 | ObserverReadConfiguredFailoverProxyProvider |
| Web UI 搜索框 | 无 | 新增 |
四、YARN 改进
1. Federation 增强
- Router 完整接口实现
- SubCluster 自动下线机制
- Kerberos 安全支持增强
- 缓存实体数量限制
- 支持 Caffeine 缓存
2. 调度器改进
- 动态队列 ACL 处理
- 队列状态转换(DRAINING → RUNNING)
- AM 默认节点标签配置
- 抢占策略优化
五、安全与依赖升级
1. 关键依赖版本
| 依赖 | 3.3.1 | 3.4.1 |
| Log4j | 1.x | reload4j |
| Jackson | 1.x + 2.x | 仅 2.12.7+ |
| Netty | 较旧版本 | 4.1.77.Final |
| Protocol Buffers | 2.5 | 3.23.4 |
| ZooKeeper Client | 较旧版本 | 3.8.4 |
| Bouncy Castle | 较旧版本 | 1.77 |
| snappy-java | 较旧版本 | 1.1.8.2 |
2. 安全修复
3.4.1 修复了多个 CVE:
- CVE-2024-23944 (ZooKeeper)
- CVE-2022-23437 (Xerces)
- CVE-2019-20444/20445 (Netty)
- 多个 Jackson CVE
六、移除的功能
| 功能 | 状态 |
hadoop-openstack 模块 | 已移除 |
| HTrace 追踪 | 替换为 No-Op |
| S3 Select | 已移除 |
trace 子命令 | 已移除 |
| Swift 文件系统 | 已移除 |
| Commons Logging(FileSystem类) | 已移除 |
七、配置变化
重要默认值变化
| 配置项 | 3.3.1 默认值 | 3.4.1 默认值 |
dfs.image.transfer.bandwidthPerSec | 0 (无限制) | 50MB/s |
dfs.namenode.quota.init-threads | 4 | 12 |
dfs.client.failover.random.order | false | true |
ipc.client.rpc-timeout.ms | 0 | 120000 |
hadoop.http.idle_timeout.ms | 10000 | 60000 |
fs.s3a.directory.marker.retention | delete | keep |
fs.abfs.enable.readahead | true | false |
八、新API与接口
| API | 描述 |
FileSystem.recoverLease() | 租约恢复 |
FileSystem.setSafeMode() | 安全模式控制 |
FileSystem.isFileClosed() | 文件关闭状态检查 |
UGI#getGroupsSet() | 高效组查询 |
PositionedReadable.readVectored() | 向量化读取 |
九、性能改进
1. NameNode
- 并行加载 FsImage 的块映射和名称缓存
- 延迟计算安全模式下的活跃 DataNode
- 减少锁竞争
2. DataNode
- 卷级别锁替代全局锁
- DirectoryScanner 优化
- 块扫描速度提升
3. 客户端
- URI 缓存减少对象创建
- LongAdder 替代 AtomicLong
- DistCp 内存优化(
-useiterator 选项)
十、依赖兼容性检查清单
1. HDFS 客户端 API 兼容性
新增 API(可选用)
| API | 用途 | 影响 |
FileSystem.recoverLease(path) | 租约恢复 | 新功能 |
FileSystem.setSafeMode(action) | 安全模式控制 | 新功能 |
FileSystem.isFileClosed(path) | 文件关闭检查 | 新功能 |
PositionedReadable.readVectored() | 向量化读取 | 性能优化 |
已移除/弃用的 API
| 变化 | 影响 | 迁移方案 |
FileSystem.LOG (commons-logging) | 已移除 | 使用私有 SLF4J Logger |
DFSClient#getGroups() | 已弃用 | 使用getGroupsSet() |
行为变化
| 变化点 | 3.3.1 | 3.4.1 | 检查项 |
| 默认字符集 | 系统默认 | UTF-8 | 检查依赖系统编码的代码 |
| RPC 超时 | 0 (无限) | 120000ms | 检查需要长超时的操作 |
| Failover 顺序 | 固定顺序 | 随机顺序 | 检查依赖特定 NN 顺序的逻辑 |
2. YARN API 兼容性
已移除的类
| 移除的类 | 替代方案 |
org.apache.hadoop.yarn.webapp.hamlet.* | 使用hamlet2 包 |
新增功能
| 功能 | 说明 |
| 动态队列 ACL | YARN-11069 |
| AM 默认节点标签 | yarn.am.default.node-label |
| 队列状态转换 | DRAINING → RUNNING |
3. 自定义扩展检查
FileSystem 自定义实现
// 旧代码(3.3.1)- 会编译失败
public class MyFileSystem extends FileSystem {
// 继承了 protected CommonsLogging LOG
}
// 新代码(3.4.1)- 必须修改
public class MyFileSystem extends FileSystem {
private static final Logger LOG = LoggerFactory.getLogger(MyFileSystem.class);
}
S3A 扩展(如果使用 S3)
| 扩展点 | 变化 |
AWSCredentialsProvider | V1 SDK 类需迁移到 V2 |
S3ACommitter | Manifest Committer 成为默认 |
| S3 Select | 已移除 |
Writable 序列化
// 如果有序列化类使用了旧类名,需添加别名
WritableName.addName("com.example.OldClass", NewClass.class);
4. 依赖版本冲突检查
需要排除的旧依赖
<!-- 排除旧的 log4j 1.x -->
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<!-- 排除 reload4j(如果不需要)-->
<exclusion>
<groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
</exclusion>
需要显式添加的依赖
<!-- 如果使用 LZ4 压缩 -->
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.8.0</version>
</dependency>
<!-- 如果使用 Snappy 压缩 -->
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.8.2</version>
</dependency>
5. 检查步骤建议
□ 1. 扫描代码中对以下包的引用:
- org.apache.hadoop.fs.s3a.S3A* (AWS SDK V2 变化)
- org.apache.hadoop.fs.FileSystem.LOG (已移除)
- org.apache.hadoop.yarn.webapp.hamlet.* (已移除)
□ 2. 检查 Maven/Gradle 依赖:
- Jackson 版本冲突(确保仅使用 2.12.7+)
- 排除 log4j 1.x 相关依赖
□ 3. 测试关键路径:
- HDFS 读写操作
- YARN 任务提交
- 自定义 Committer/FileSystem
□ 4. 验证配置:
- rpc-timeout 相关配置
- 编码相关(UTF-8)
十一、升级建议
从 3.3.1 升级到 3.4.1 需要:
- 检查依赖兼容性 - AWS SDK V2 变化较大
- 验证 S3 Select 使用 - 该功能已移除
- 调整 ABFS 配置 - 默认值有变化
- 测试 Log4j 配置 - 迁移到 reload4j
- 审查自定义代码 - 移除的 API 和类
十二、Protocol Buffers 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| Protocol Buffers 版本 | 2.5.0 | 3.21.12 ~ 3.23.4 |
| protobuf-java | 2.5.0 | 3.23.4 |
| protoc 编译器 | 2.5.x | 23.x |
| 协议格式 | proto2 | proto2 + proto3 |
2. 核心兼容性问题
2.1 二进制兼容性(关键问题)
问题:Proto2 和 Proto3 生成的 Java 类不兼容
| 兼容性层面 | 状态 | 说明 |
| 线格式(Wire Format) | ✅ 兼容 | 二进制序列化格式不变,旧数据可被新版本读取 |
| Java API | ❌ 不兼容 | 生成的 Java 类 API 完全不同 |
| 运行时类 | ❌ 不兼容 | protobuf-java 2.x 和 3.x 不能共存 |
影响范围:
- 所有依赖 Hadoop RPC 通信的组件
- 自定义 Writable 序列化
- YARN/MapReduce 协议消息
2.2 Java API 变化
Proto2 (Hadoop 3.3.1):
// 生成的 Message 类
public class MyMessage extends GeneratedMessage {
// 使用 Builder 模式
public static MyMessage parseFrom(byte[] data);
// 字段访问
public String getName();
public boolean hasName();
}
Proto3 (Hadoop 3.4.1):
// 生成的 Message 类(API 变化)
public class MyMessage extends GeneratedMessageV3 {
// 解析方法类似但实现不同
public static MyMessage parseFrom(byte[] data);
// 字段访问 - 空字段处理不同
public String getName(); // 空字段返回空字符串而非 null
// 新增方法
public Builder toBuilder();
}
2.3 依赖冲突
类路径冲突问题:
| 冲突类 | 3.3.1 | 3.4.1 |
com.google.protobuf.Message | 2.5.0 | 3.23.4 |
com.google.protobuf.GeneratedMessage | 2.5.0 | 3.23.4 (GeneratedMessageV3) |
com.google.protobuf.CodedInputStream | 2.5.0 | 3.23.4 |
同一个 JVM 中不能同时存在两个版本!
3. Hadoop 组件影响分析
3.1 HDFS RPC 协议
| 协议 | 影响 | 说明 |
| ClientProtocol | 🔴 高 | 客户端与 NameNode 通信 |
| DatanodeProtocol | 🔴 高 | DataNode 与 NameNode 通信 |
| JournalProtocol | 🟡 中 | JournalNode 同步 |
| HAServiceProtocol | 🟡 中 | NameNode HA |
影响:所有跨版本 RPC 调用都会失败
3.2 YARN 协议
| 协议 | 影响 | 说明 |
| ApplicationClientProtocol | 🔴 高 | 客户端提交作业 |
| ApplicationMasterProtocol | 🔴 高 | AM 与 RM 通信 |
| ContainerManagementProtocol | 🔴 高 | AM 与 NM 通信 |
3.3 MapReduce
4. 具体兼容性问题
问题 1:混合版本集群不兼容
┌─────────────────┐ ┌─────────────────┐
│ Hadoop 3.3.1 │ ─RPC─▶ │ Hadoop 3.4.1 │
│ (Proto 2.5) │ ✗ │ (Proto 3.23) │
└─────────────────┘ └─────────────────┘
错误:Protobuf 版本不匹配,无法反序列化消息
结论:集群必须统一升级,不能混版本运行
问题 2:自定义协议扩展
如果项目自定义了 Hadoop 协议(如自定义 Committer、自定义插件):
// 旧代码(使用 Proto 2.5 生成的类)
public class MyCustomProtocol implements ProtocolProxy {
MyMessage parseRequest(byte[] data) {
return MyMessage.parseFrom(data); // Proto 2.5 API
}
}
// 升级后需要重新生成类并修改代码
public class MyCustomProtocol implements ProtocolProxy {
MyMessage parseRequest(byte[] data) {
return MyMessage.parseFrom(data); // Proto 3.x API,但类已重新生成
}
}
问题 3:第三方依赖冲突
| 第三方组件 | 潜在冲突 | 解决方案 |
| Spark | 可能使用旧版 protobuf | 显式依赖新版本 |
| Flink | 可能使用旧版 protobuf | 使用 shade 重定位 |
| HBase | 使用自己的 protobuf | 独立管理依赖 |
| Kafka | 内置 protobuf | 版本需对齐 |
5. Hadoop 的缓解策略
5.1 hadoop-thirdparty 项目
Hadoop 3.4.x 使用 hadoop-thirdparty 来重定位 protobuf:
<dependency>
<groupId>org.apache.hadoop.thirdparty</groupId>
<artifactId>hadoop-shaded-protobuf_3_25</artifactId>
<version>1.3.0</version>
</dependency>
作用:
- 将 protobuf 类重定位到
org.apache.hadoop.thirdparty.protobuf.*
- 允许 Hadoop 内部使用新版 protobuf
- 隔离外部依赖冲突
5.2 相关 JIRA
| JIRA | 描述 |
| HADOOP-16604 | 升级 protobuf 相关讨论 |
| YARN-11657 | 移除 protobuf 2.5 作为 yarn-api 依赖 |
| HADOOP-19065 | 更新 Protocol Buffers 到 3.21.12 |
| HADOOP-19090 | 更新 Protocol Buffers 到 3.23.4 |
6. 迁移检查清单
□ 1. 检查项目依赖
├─ 搜索所有 protobuf-java 依赖
├─ 确认版本统一为 3.23.x+
└─ 排除冲突的 protobuf 2.x
□ 2. 重新生成 Protocol 类
├─ 使用新版 protoc (23.x) 重新编译 .proto 文件
└─ 更新所有生成的 Java 类
□ 3. 检查代码兼容性
├─ 检查 hasXxx() 方法调用(proto3 中空值处理不同)
├─ 检查字段默认值逻辑
└─ 检查 Builder 模式使用
□ 4. 验证第三方组件
├─ Spark/Flink 等的 protobuf 版本
└─ 必要时使用 shade 插件重定位
□ 5. 集群升级策略
├─ 全量升级,不支持滚动升级
└─ 升级期间服务不可用
7. 升级建议
| 场景 | 建议 |
| 纯 Hadoop 集群 | 全量升级,确保所有节点版本一致 |
| 依赖 Spark/Flink | 确认兼容性后统一升级 |
| 自定义 RPC 协议 | 重新生成 protobuf 类并测试 |
| 多租户环境 | 统一 protobuf 版本,避免冲突 |
8. 核心结论
Protocol Buffers 2.5 → 3.23 是一个不兼容的破坏性升级。升级时必须:
- 全集群统一升级 - 不支持混合版本
- 重新生成所有 protobuf 类 - 使用新版 protoc
- 处理第三方依赖冲突 - 确保 protobuf 版本一致
十三、Log4j 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| Log4j 版本 | 1.2.x (log4j 1.x) | reload4j 1.2.18+ |
| 包命名空间 | org.apache.log4j | org.apache.log4j (兼容) |
| 配置文件 | log4j.properties / log4j.xml | log4j.properties / log4j.xml |
| 维护状态 | 已 EOL (2015年) | 社区维护 fork |
2. Log4j 1.x EOL 背景说明
Log4j 1.x 于 2015 年停止维护,2015 年 8 月后报告的漏洞不再修复。reload4j 是 Log4j 1.x 的社区维护分支,修复了关键安全问题。
3. 核心兼容性问题
3.1 API 兼容性
| 兼容性层面 | 状态 | 说明 |
| 包名 | ✅ 兼容 | 均为org.apache.log4j |
| 配置文件 | ✅ 兼容 | 格式完全兼容 |
| 二进制兼容 | ✅ 兼容 | drop-in 替换 |
| 行为一致性 | 🟡 基本兼容 | 少数边缘情况可能不同 |
3.2 主要变化
reload4j 相对于 Log4j 1.x 的改进:
-
安全修复
- 修复了 Log4j 1.x 的已知安全漏洞
- 移除了有风险的 JMSAppender 默认配置
- 加强了配置文件加载的安全性
-
行为变化
- 默认禁用某些不安全的功能
- 改进了错误处理和日志输出
4. 迁移影响
4.1 无需修改的场景
以下场景可以直接替换,无需修改代码:
- 使用标准 Log4j 1.x API 的应用
- 使用
log4j.properties 或 log4j.xml 配置
- 使用标准 Appender(ConsoleAppender、FileAppender 等)
4.2 需要检查的场景
| 场景 | 检查项 |
| 自定义 Appender | 验证兼容性 |
| JMSAppender | 检查配置是否被禁用 |
| SocketAppender | 验证连接配置 |
| 自定义 Layout | 验证输出格式 |
4.3 配置文件兼容性
# log4j.properties - 完全兼容
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
5. 相关 JIRA
| JIRA | 描述 |
| HADOOP-18088 | Replace log4j 1.x with reload4j |
6. 迁移建议
□ 1. 更新 Maven 依赖
<dependency>
<groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId>
<version>1.2.25</version>
</dependency>
□ 2. 排除旧的 log4j 依赖
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
□ 3. 验证日志配置文件
□ 4. 测试关键日志输出
十四、Jackson 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| Jackson 1.x | 存在 | 已移除 |
| Jackson 2.x | 2.x (多版本) | 仅 2.12.7+ |
| jackson-core | 多版本 | 2.12.7 |
| jackson-databind | 多版本 | 2.12.7 |
| jackson-annotations | 多版本 | 2.12.7 |
2. 核心兼容性问题
2.1 Jackson 1.x 完全移除
Hadoop 3.4.1 完全移除了 Jackson 1.x 依赖:
| 影响 | 说明 |
| API 不兼容 | org.codehaus.jackson.* 包不再存在 |
| 类路径冲突 | 必须确保没有 Jackson 1.x 残留 |
| 第三方库 | 检查依赖是否使用 Jackson 1.x |
2.2 Jackson 2.x 版本统一
Hadoop 3.4.1 统一使用 Jackson 2.12.7:
<!-- 统一版本 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.7</version>
</dependency>
3. Jackson 2.12 重要变化
3.1 新特性
| 特性 | 说明 |
| Java 14 Record 支持 | 原生支持java.lang.Record |
| CoercionConfig | 可配置的类型强制转换规则 |
@JsonIncludeProperties | 白名单式属性包含 |
| 多态类型推导 | @JsonTypeInfo(use=DEDUCTION) |
| ConstructorDetector | 注解无关的构造函数检测 |
3.2 行为变化
| 变化 | 影响 |
| 空字符串处理 | XML 模块EMPTY_ELEMENT_AS_NULL 默认改为 false |
| 单字段 Record | 绑定方式从 Delegating 改为 Properties |
| JDK 基线 | 最低 JDK 7(部分模块需要 JDK 8) |
4. 迁移影响
4.1 包名迁移
// 旧代码(Jackson 1.x)- 不再支持
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.JsonNode;
// 新代码(Jackson 2.x)
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
4.2 API 变化
| Jackson 1.x | Jackson 2.x |
ObjectMapper.serialize() | ObjectMapper.writeValueAsString() |
ObjectMapper.deserialize() | ObjectMapper.readValue() |
JsonNode.getPath() | JsonNode.at() |
4.3 第三方依赖检查
| 组件 | 检查项 |
| Spark | 内置 Jackson 版本 |
| Flink | 内置 Jackson 版本 |
| Spring | 版本兼容性 |
| Jersey | JSON 处理配置 |
5. 相关 JIRA
| JIRA | 描述 |
| HADOOP-15983 | Use jersey-json that is built to use jackson2 |
| HADOOP-18332 | Remove rs-api dependency by downgrading jackson to 2.12.7 |
6. 迁移建议
□ 1. 扫描代码中 Jackson 1.x 引用
grep -r "org.codehaus.jackson" .
□ 2. 更新 Maven 依赖
- 确保只使用 Jackson 2.x
- 排除 Jackson 1.x 传递依赖
□ 3. 修改代码中的包名导入
□ 4. 验证 JSON 序列化/反序列化
□ 5. 检查第三方组件兼容性
十五、Netty 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| Netty 版本 | 3.x / 4.0.x | 4.1.77.Final |
| netty-all | 较旧版本 | 4.1.77.Final |
| netty-buffer | 较旧版本 | 4.1.77.Final |
| netty-codec | 较旧版本 | 4.1.77.Final |
2. 安全修复
Hadoop 3.4.1 升级 Netty 修复了以下 CVE:
| CVE | 描述 | 严重程度 |
| CVE-2019-20444 | HTTP 请求走私漏洞 | 高 |
| CVE-2019-20445 | HTTP 请求走私漏洞 | 高 |
| CVE-2022-24823 | 资源管理错误 | 中 |
3. 核心兼容性问题
3.1 Netty 3.x → 4.x 破坏性变化
| 变化 | 影响 |
| 包名 | org.jboss.netty.* → io.netty.* |
| API 重构 | 大部分 API 不兼容 |
| Buffer 模型 | ChannelBuffer → ByteBuf |
| Channel 体系 | 完全重构 |
3.2 Netty 4.0.x → 4.1.x 变化
| 变化 | 说明 |
| 内存管理 | 改进的内存分配器 |
| SSL/TLS | 更好的 SSL 支持 |
| HTTP/2 | 原生 HTTP/2 支持 |
| 性能优化 | 多项性能改进 |
4. Hadoop 中的 Netty 使用
| 组件 | 用途 |
| HDFS DataNode | 数据传输 |
| YARN NodeManager | Container 通信 |
| MapReduce Shuffle | Shuffle 服务 |
| WebHDFS | HTTP 服务 |
5. 迁移影响
5.1 包名变化
// 旧代码(Netty 3.x)
import org.jboss.netty.channel.Channel;
import org.jboss.netty.buffer.ChannelBuffer;
// 新代码(Netty 4.x)
import io.netty.channel.Channel;
import io.netty.buffer.ByteBuf;
5.2 Buffer API 变化
// Netty 3.x
ChannelBuffer buffer = ChannelBuffers.buffer(1024);
buffer.writeBytes(data);
// Netty 4.x
ByteBuf buffer = Unpooled.buffer(1024);
buffer.writeBytes(data);
5.3 Channel 变化
// Netty 3.x
Channel channel = ...;
channel.write(message); // 直接写入
// Netty 4.x
Channel channel = ...;
channel.writeAndFlush(message); // 需要显式 flush
6. 迁移建议
□ 1. 检查代码中 Netty 包引用
grep -r "org.jboss.netty" .
□ 2. 更新 Maven 依赖到 4.1.77.Final
□ 3. 修改导入语句
org.jboss.netty.* → io.netty.*
□ 4. 更新 Buffer 相关代码
ChannelBuffer → ByteBuf
□ 5. 更新 Channel 操作
write() → writeAndFlush()
□ 6. 验证网络通信功能
十六、Bouncy Castle 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| Bouncy Castle 版本 | 1.60-1.68 | 1.77+ |
| bcprov-jdk15on | 较旧版本 | 1.77 |
| bcprov-jdk18on | 无 | 新增 |
| 多版本 JAR | 无 | 支持 |
2. 多版本 JAR 特性
Bouncy Castle 1.68+ 是多版本 JAR(Multi-Release JAR),包含针对不同 JDK 版本优化的代码:
META-INF/versions/
├── 9/ # JDK 9+
├── 11/ # JDK 11+
└── 17/ # JDK 17+
3. 核心兼容性问题
3.1 JDK 版本要求
| Bouncy Castle 版本 | JDK 要求 | 说明 |
| bcprov-jdk15on | JDK 1.5+ | 旧版本 |
| bcprov-jdk18on | JDK 18+ | 新版本 |
3.2 API 变化
| 变化 | 影响 |
| 安全提供者注册 | 可能需要重新配置 |
| 加密算法 | 新增算法支持 |
| 弃用 API | 部分旧 API 被标记弃用 |
4. 加密功能影响
| 功能 | 3.3.1 | 3.4.1 |
| SM4 加密 | 无 | 支持 |
| AES-GCM | 支持 | 改进 |
| RSA | 支持 | 改进 |
| ECC | 支持 | 改进 |
5. Hadoop 中的使用场景
| 组件 | 用途 |
| HDFS 加密 | 数据加密 |
| KMS | 密钥管理 |
| Security | 认证加密 |
| WebHDFS | HTTPS 加密 |
6. 迁移建议
□ 1. 更新 Maven 依赖
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.77</version>
</dependency>
□ 2. 检查 Security Provider 配置
Security.addProvider(new BouncyCastleProvider());
□ 3. 验证加密功能
- HDFS 加密区域
- KMS 密钥操作
- HTTPS 通信
□ 4. 检查 ASM 版本兼容性
- Bouncy Castle 1.68+ 可能与旧版 ASM 冲突
十七、snappy-java 版本变化兼容性分析
1. 版本变化概览
| 项目 | Hadoop 3.3.1 | Hadoop 3.4.1 |
| snappy-java 版本 | 1.1.7.x | 1.1.8.2 |
| 压缩编解码器 | 需要原生库 | 内置原生库 |
| 平台支持 | 需手动配置 | 跨平台支持 |
2. 核心改进
2.1 内置原生库
snappy-java 1.1.8+ 内置了多平台原生库:
| 平台 | 架构 | 支持 |
| Linux | x86_64 | ✅ |
| Linux | aarch64 | ✅ |
| Windows | x86_64 | ✅ |
| macOS | x86_64 | ✅ |
| macOS | aarch64 (M1) | ✅ |
2.2 纯 Java 回退
当原生库不可用时,自动回退到纯 Java 实现。
3. SnappyCodec 变化
Hadoop 3.4.1 使用 snappy-java 替代原生 Snappy:
// Hadoop 3.3.1 - 需要系统安装 snappy
// 配置: 需要安装 libsnappy-dev
// Hadoop 3.4.1 - 使用 snappy-java
// 无需额外安装,开箱即用
4. 配置变化
<!-- Hadoop 3.4.1 压缩配置 -->
<property>
<name>io.compression.codec.snappy.java.class</name>
<value>org.apache.hadoop.io.compress.snappy.SnappyCodec</value>
</property>
5. 性能对比
| 版本 | 压缩速度 | 解压速度 | 压缩率 |
| 1.1.7 | 基准 | 基准 | 基准 |
| 1.1.8.2 | +5% | +3% | 持平 |
6. 迁移影响
6.1 依赖更新
<!-- 添加 snappy-java 依赖 -->
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.8.2</version>
</dependency>
6.2 系统要求变化
| 项目 | 3.3.1 | 3.4.1 |
| 系统安装 Snappy | 需要 | 不需要 |
| 原生库路径配置 | 需要 | 不需要 |
| 跨平台部署 | 复杂 | 简单 |
7. 相关 JIRA
| JIRA | 描述 |
| HADOOP-17125 | Using snappy-java in SnappyCodec |
| HADOOP-17425 | Bump up snappy-java to 1.1.8.2 |
8. 迁移建议
□ 1. 更新 Maven 依赖到 1.1.8.2
□ 2. 移除系统 Snappy 安装要求
- 不再需要 libsnappy-dev
- 不再需要配置原生库路径
□ 3. 验证压缩功能
- MapReduce 输出压缩
- HDFS 文件压缩
- 中间数据压缩
□ 4. 测试跨平台兼容性
- Linux x86_64
- Linux aarch64
- macOS M1
十八、依赖兼容性总结
1. 版本变化汇总表
| 依赖 | 3.3.1 | 3.4.1 | 兼容性 |
| Log4j | 1.2.x | reload4j 1.2.x | ✅ 兼容 |
| Jackson | 1.x + 2.x | 仅 2.12.7 | 🟡 需迁移 |
| Netty | 3.x/4.0.x | 4.1.77 | 🟡 需迁移 |
| Bouncy Castle | 1.60-1.68 | 1.77+ | ✅ 兼容 |
| snappy-java | 1.1.7.x | 1.1.8.2 | ✅ 改进 |
| Protocol Buffers | 2.5 | 3.23.4 | ❌ 不兼容 |
2. 迁移优先级
| 优先级 | 依赖 | 原因 |
| P0 | Protocol Buffers | RPC 通信完全中断 |
| P1 | Jackson | API 不兼容,JSON 处理失败 |
| P1 | Netty | 网络通信问题 |
| P2 | Log4j | 需验证配置 |
| P3 | Bouncy Castle | 通常向后兼容 |
| P3 | snappy-java | 自动回退机制 |
3. 检查清单
□ Protocol Buffers
├─ 全集群统一升级
├─ 重新生成 proto 类
└─ 处理依赖冲突
□ Jackson
├─ 移除 Jackson 1.x 依赖
├─ 更新包名导入
└─ 验证 JSON 处理
□ Netty
├─ 更新包名导入
├─ 修改 Buffer/Channel API
└─ 验证网络通信
□ Log4j
├─ 更新依赖到 reload4j
├─ 排除旧 log4j
└─ 验证日志配置
□ Bouncy Castle
├─ 更新依赖版本
├─ 检查 Provider 配置
└─ 验证加密功能
□ snappy-java
├─ 更新依赖版本
├─ 移除原生库配置
└─ 验证压缩功能
参考资料