测试背景
将 MongoDB Java 驱动从 4.11.5
升级至 5.5.1
,并配合 Reactor Core 3.8.0-M4
进行性能对比测试。测试主要围绕插入、查询、更新和删除四个核心操作进行。
环境配置
- 操作系统: Windows 11
- CPU: Intel® Core™ i7-14700F, 28 核心, 2.10 GHz
- JDK: OpenJDK 21.0.7 (TencentKonaJDK)
- MongoDB 驱动版本:
- 旧版本:
org.mongodb:mongodb-driver-reactivestreams:4.11.5
,org.mongodb:bson:4.11.5
- 新版本:
org.mongodb:mongodb-driver-reactivestreams:5.5.1
,org.mongodb:bson:5.5.1
- 旧版本:
- Reactor Core 版本:
- 旧版本:
io.projectreactor:reactor-core:3.4.41
- 新版本:
io.projectreactor:reactor-core:3.8.0-M4
- 旧版本:
- 线程数: 4 线程
- MongoClient 配置:
以下是 MongoDB 客户端连接池配置参数及其值
参数名 | 值 | 中文含义 | 说明 |
---|---|---|---|
maxPoolSize | 48 | 最大连接池大小 | 连接池中最多可以保持的连接数。 |
minPoolSize | 8 | 最小连接池大小 | 连接池中始终保持的最小连接数。 |
connectTimeoutMs | 5000 | 连接超时时间(毫秒) | 建立连接的最大等待时间,单位为毫秒。 |
socketTimeoutMs | 10000 | 套接字超时时间(毫秒) | 读取数据时等待响应的最大时间,单位为毫秒。 |
maxWaitTimeMs | 10000 | 获取连接最大等待时间(毫秒) | 当连接池没有可用连接时,请求连接的最大等待时间,单位为毫秒。 |
maxIdleTimeSec | 900 | 连接最大空闲时间(秒) | 连接在池中保持空闲而不被释放的时间,单位为秒。 |
maxConnecting | 4 | 最大同时建立连接数 | 同时尝试建立的新连接的最大数量。 |
readTimeoutMs | 10000 | 读取超时时间(毫秒) | 等待从服务器读取数据的最大时间,单位为毫秒。与 socketTimeout 类似。 |
性能对比概览(含三阶段对比)
测试类:com.ooxx.common.db.MongoPerfTest
操作类型 | 未调优 (4.11.5) | 调优后 (4.11.5) | 升级后 (5.5.1) | 提升幅度(未调优 ➜ 升级后) |
---|---|---|---|---|
插入 | 5,459 条/秒 | 9,507 条/秒 | 10,550 条/秒 | +93.3% |
查询 | 5,894 次/秒 | 9,883 次/秒 | 10,541 次/秒 | +78.8% |
更新 | 5,653 次/秒 | 9,987 次/秒 | 10,488 次/秒 | +85.5% |
删除 | 5,718 次/秒 | 10,969 次/秒 | 11,883 次/秒 | +107.9% |
阶段性分析
第一阶段:从“未调优”到“调优”
- 使用 NettyTransportSettings 线程池配置优化
- 性能平均提升约 70~90%
- 说明线程模型和连接池参数对性能影响巨大
第二阶段:驱动升级(4.11.5 ➜ 5.5.1)
- 在已调优基础上继续提升 5~11%
- 说明新版本底层协议、序列化或 Reactor 支持有进一步优化
- 对删除操作优化尤为明显(+8.3%)
综合收益:从原始未调优 ➜ 最终优化版
- 整体吞吐量接近 翻倍
详细分析
✅ 未调优 vs 调优(驱动版本不变:4.11.5)
- 提升显著:使用 NettyTransportSettings并优化连接池参数后,所有操作性能几乎翻倍。
- 插入从 5,459 ➜ 9,507 (+74%)
- 查询从 5,894 ➜ 9,883 (+67.7%)
- 更新从 5,653 ➜ 9,987 (+76.7%)
- 删除从 5,718 ➜ 10,969 (+92.7%)
结论:调优对性能影响巨大,特别是在高并发场景下,合理配置线程模型和连接池是关键。
✅ 调优后 4.11.5 ➜ 5.5.1
- 进一步提升:MongoDB 驱动从 4.11.5 升级到 5.5.1 后,性能仍有明显提升,说明新版本在底层网络处理、序列化优化或 Reactor 支持方面有改进。
- 插入从 9,507 ➜ 10,550 (+11%)
- 查询从 9,883 ➜ 10,541 (+6.7%)
- 更新从 9,987 ➜ 10,488 (+5.0%)
- 删除从 10,969 ➜ 11,883 (+8.3%)
结论:驱动升级带来额外 5~11% 的性能提升。
技术建议与总结
组件 | 建议值 |
---|---|
MongoDB 驱动版本 | 5.5.1 |
使用 Transport | NettyTransportSettings |
EventLoopGroup 线程数 | CPU 核心数 × 2(不超过 8~12) |
连接池大小 ([maxPoolSize | 48 |
最小连接数 | 8 |
最大并发连接数 | 4 |
最大等待时间 | 10,000 ms |
最大空闲时间 | 900 s |
读写超时时间 | 10,000 ms |
线程池 | 固定线程数(根据业务负载调整) |
性能趋势图示意
插入性能:
[4.11.5 未调优] → [4.11.5 调优] → [5.5.1 调优]
5,459 → 9,507 → 10,550查询性能:
[4.11.5 未调优] → [4.11.5 调优] → [5.5.1 调优]
5,894 → 9,883 → 10,541更新性能:
[4.11.5 未调优] → [4.11.5 调优] → [5.5.1 调优]
5,653 → 9,987 → 10,488删除性能:
[4.11.5 未调优] → [4.11.5 调优] → [5.5.1 调优]
5,718 → 10,969 → 11,883
最终结论
- 调优 > 升级:优化线程模型和连接池配置带来的性能提升远大于单纯升级驱动。
- 升级有益无害:MongoDB 5.5.1 在调优基础上仍能带来 5~11% 的额外性能收益。
TODO
在 JDK21 虚拟线程环境下适配 MongoDB 时,同步驱动相比响应式驱动更具优势,核心原因在于虚拟线程通过轻量级线程模型消除了同步阻塞的代价,使传统同步代码既能保持简洁性,又能获得媲美响应式的高并发性能。同步驱动无需响应式编程的复杂回调链,响应式编程的核心价值原本是解决线程阻塞问题,但虚拟线程已从底层化解该痛点,其复杂的异步代码风格反而成为负担,后期可能将考虑改成同步驱动。