存储引擎 Benchmark 实战:RocksDB 与 WiredTiger 在混合负载下的性能对比
存储引擎 Benchmark 实战:RocksDB 与 WiredTiger 在混合负载下的性能对比
一、Benchmark 不是跑一遍 sysbench 就交差
每当需要在 RocksDB 和 WiredTiger 之间做选型时,最常见的做法是:用 sysbench 跑一套标准的读写混合负载,然后比较 TPS 和延迟。这个做法没错,但它测的是"这两种引擎在理想条件下的表现",而不是"在你的业务负载下的表现"。
问题出在两个方面。第一,sysbench 的默认负载是均匀分布的主键读写,而真实业务的访问模式往往有明显的冷热分层——80% 的请求集中在 20% 的热数据上。第二,Benchmark 通常只跑 10 分钟或 30 分钟,这不足以激发 LSM-Tree(RocksDB)的 Compaction 或 B-Tree(WiredTiger)的 Page Split——而这两种后台操作恰恰是决定稳态性能的关键。
一次有说服力的 Benchmark,必须回答三个问题:在什么样的数据量级、什么样的访问分布、运行多长时间后,引擎的表现如何。
flowchart TD
A[Benchmark 设计] --> B[定义负载模型]
B --> C[点查/范围扫描占比]
B --> D[读写比例]
B --> E[冷热数据分布]
B --> F[数据量级]
C --> G[执行 Benchmark]
D --> G
E --> G
F --> G
G --> H[预热阶段: 30 分钟]
H --> I[稳态测试: 2 小时]
I --> J[采集指标]
J --> K[吞吐: OPS]
J --> L[延迟: P50/P95/P99]
J --> M[后台活动: Compaction/Page Split 频率]
J --> N[资源: CPU/IO/内存]
K --> O[分析报告]
L --> O
M --> O
N --> O
二、测试环境与负载模型的定义
测试硬件统一为 16 核 CPU、64GB 内存、NVMe SSD(1TB),操作系统为 CentOS 7.9,文件系统为 XFS。数据量级分两档:小数据集(10GB,数据全在内存)和大数据集(200GB,远超内存容量)。这是有意为之——在小数据集上,两种引擎都在内存中运行,测的是纯 CPU 效率;在大数据集上,I/O 成为瓶颈,测的是引擎对磁盘的利用策略。
负载模型的设计比硬件更重要。定义三种负载:
负载 A(读写均衡):50% 点查 + 30% 范围扫描(每次扫描 100 行) + 20% 插入,Zipfian 分布(α=1.2,模拟热数据集中)。
负载 B(写密集):70% 插入 + 20% 更新 + 10% 点查,均匀分布。
负载 C(读密集):90% 点查 + 10% 范围扫描,Zipfian 分布。
# 基于 YCSB 的负载生成配置(Python 驱动)
test_configs = {
"workload_a": { # 读写均衡
"read_proportion": 0.5,
"scan_proportion": 0.3,
"insert_proportion": 0.2,
"request_distribution": "zipfian",
"zipfian_constant": 1.2,
"scan_length": 100,
},
"workload_b": { # 写密集
"read_proportion": 0.1,
"update_proportion": 0.2,
"insert_proportion": 0.7,
"request_distribution": "uniform",
},
"workload_c": { # 读密集
"read_proportion": 0.9,
"scan_proportion": 0.1,
"request_distribution": "zipfian",
"zipfian_constant": 1.2,
}
}
三、核心对比结果与数据解读
小数据集(10GB)下的表现:
| 指标 | RocksDB | WiredTiger |
|---|---|---|
| 负载 A - 吞吐 (ops/s) | 82,300 | 91,500 |
| 负载 A - P99 延迟 (μs) | 4,200 | 2,800 |
| 负载 B - 吞吐 (ops/s) | 115,000 | 78,000 |
| 负载 B - P99 延迟 (μs) | 3,100 | 8,500 |
| 负载 C - 吞吐 (ops/s) | 95,000 | 135,000 |
| 负载 C - P99 延迟 (μs) | 1,800 | 950 |
在小数据集上,WiredTiger 的读性能显著优于 RocksDB。原因在于 B-Tree 的 O(log_B N) 查找 + 内存缓存,在 N 不大时效率极高。而 RocksDB 的 LSM-Tree 读路径需要逐层查找——先查 MemTable,然后 L0 → L1 → L2……直到找到目标。在小数据量下,LSM-Tree 的写放大换来的 Compaction 优化没有用武之地,反而在读取上做了额外的查找工作。
但写密集负载(负载 B)是另一番景象——RocksDB 的 LSM-Tree 将随机写转为顺序写(Write-Ahead Log + MemTable flush),吞吐比 WiredTiger 高出近 50%。WiredTiger 的 B-Tree 在写密集场景下频繁触发 Page Split,加上 WAL 的同步写入,写性能显著下降。
大数据集(200GB)下的表现:
| 指标 | RocksDB | WiredTiger |
|---|---|---|
| 负载 A - 吞吐 (ops/s) | 36,000 | 12,800 |
| 负载 A - P99 延迟 (ms) | 12.5 | 48.2 |
| 负载 C - 吞吐 (ops/s) | 42,000 | 8,500 |
| 负载 C - P99 延迟 (ms) | 8.7 | 112.3 |
大数据集彻底翻转了战局。WiredTiger 的 B-Tree 页缓存(Page Cache)在 64GB 内存 vs 200GB 数据的条件下严重不足,大部分读取需要回磁盘。而 RocksDB 的 Block Cache + 布隆过滤器 + 分层压缩使得热数据被有效地保留在较高层级,磁盘 I/O 的次数远少于 WiredTiger。此外,ZSTD 压缩对 RocksDB Block 的压缩率好于 WiredTiger 的 Snappy 默认压缩。
flowchart LR
subgraph WiredTiger_BTree
W1[内存: Page Cache] -->|缓存未命中| W2[磁盘: B-Tree 页]
W2 -->|Page Split| W3[磁盘: 新页分配]
W3 --> W2
end
subgraph RocksDB_LSM
R1[内存: MemTable] -->|flush| R2[磁盘: L0 SST]
R1 -->|读| R3[内存: Block Cache]
R2 -->|Compaction| R4[磁盘: L1~L6 SST]
R4 -->|读| R3
R3 -->|布隆过滤| R5[快速判断 Key 不存在]
end
四、选型决策树与工程建议
Benchmark 结果指向一个清晰的选型决策框架:
选 WiredTiger:数据量可控(<50GB)、读密集负载、需要 ACID 事务、已有 MongoDB 或单机 MySQL 技术栈。典型场景:用户画像存储、配置管理、小型 OLTP。
选 RocksDB:数据量超过内存容量(>100GB)、写密集或混合负载、对延迟敏感、需要高压缩率。典型场景:时序数据库底层存储、消息队列的 Offset 存储、日志搜索引擎的倒排索引。
两者同时使用:利用不同引擎的特性做分层存储。热数据层用 WiredTiger 提供低延迟读写,冷数据层用 RocksDB 提供高压缩和低成本存储。应用层通过时间或访问频率策略做数据在两层之间的自动迁移。
选型之后还有三个工程注意事项:第一,无论选哪个引擎,都必须在生产环境的真实硬件上跑至少 24 小时的稳态测试——Compaction 和 Page Split 的副作用通常在 4 小时之后才会显现;第二,监控 Compaction 的 Write Stall(RocksDB)或 Eviction 压力(WiredTiger),这是存储引擎向你发出的"我快扛不住了"的信号;第三,不要把 Benchmark 的数字当做 SLA 承诺——Benchmark 是在无干扰环境中跑出来的,生产环境还有网络抖动、并发竞争和操作系统调度延迟。
五、总结
RocksDB 和 WiredTiger 没有绝对的优劣,只有场景的适合与否。Benchmark 的目标不是选出一个"赢家",而是搞清楚每种引擎的"舒适区"和"禁区"。在 200GB+ 数据量、混合负载的场景下,RocksDB 的 LSM-Tree 架构在写入吞吐和磁盘效率上的优势是结构性的——这不是调参数能弥补的差距。在小数据量、读密集的场景下,WiredTiger 的 B-Tree 简洁高效。做选型时,最不应该犯的错误是拿小数据集的 Benchmark 去预测大数据集的表现——两种引擎的"相变点"可能就在某个数据量级上悄然发生。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)