LevelDB 完全指南 / 第 14 章 · LevelDB vs RocksDB
第 14 章 · LevelDB vs RocksDB
14.1 RocksDB 的诞生
RocksDB 是 Facebook 于 2013 年从 LevelDB 分支出来的一个项目。它的目标是在 LevelDB 的基础上,针对大规模生产环境进行优化,特别是 SSD 和多核场景。
时间线:
2011: Google 开源 LevelDB
2012: Facebook 在内部使用 LevelDB,发现性能瓶颈
2013: RocksDB 从 LevelDB 1.5 分支,开始独立发展
2014: RocksDB 3.0,引入 Column Family
2015: RocksDB 4.0,Universal Compaction
2018: RocksDB 5.0,BlobDB(Value 分离)
2021: RocksDB 6.0,Remote Compaction
2023: RocksDB 8.0,持续活跃开发
14.2 核心特性对比
存储与写入
| 特性 |
LevelDB |
RocksDB |
| 存储引擎 |
LSM-Tree |
LSM-Tree |
| 并发写入 |
❌ 单写者 |
✅ 多写者 |
| WriteBatch |
✅ |
✅ |
| Column Family |
❌ |
✅ |
| 原子写入 |
✅ 单批次 |
✅ 跨 CF 原子写入 |
Compaction
| 特性 |
LevelDB |
RocksDB |
| Compaction 策略 |
Level-based |
Level / Universal / FIFO |
| 后台线程数 |
1 |
可配置(多线程) |
| 手动 Compaction |
✅ CompactRange |
✅ 更多控制选项 |
| Remote Compaction |
❌ |
✅ |
| 动态调整 |
❌ |
✅ 动态调整 Compaction 参数 |
压缩
| 特性 |
LevelDB |
RocksDB |
| 压缩算法 |
Snappy(默认) |
Snappy / Zlib / LZ4 / ZSTD / 无 |
| 每层独立压缩 |
❌ |
✅ 不同层使用不同压缩 |
| 字典压缩 |
❌ |
✅ (ZSTD) |
| 压缩线程 |
同步 |
异步(可配置并行度) |
缓存与内存
| 特性 |
LevelDB |
RocksDB |
| Block Cache |
LRU |
LRU / Clock / 自定义 |
| Cache 分片 |
❌ |
✅ (ShardedCache) |
| 内存表 |
SkipList |
SkipList / HashSkipList / Vector / HashLinkList |
| 压缩表(前缀) |
❌ |
✅ Prefix Bloom |
备份与复制
| 特性 |
LevelDB |
RocksDB |
| 内置备份 |
❌ |
✅ (BackupEngine) |
| Checkpoint |
❌ |
✅ (硬链接快照) |
| Change Data Capture |
❌ |
✅ (WalFilter) |
| 跨列族 Snapshot |
❌ |
✅ |
14.3 性能对比
基准测试结果(NVMe SSD,100GB 数据集)
| 测试项 |
LevelDB |
RocksDB |
提升 |
| 顺序写入 |
150 MB/s |
350 MB/s |
2.3x |
| 随机写入 |
30 MB/s |
150 MB/s |
5x |
| 顺序读取 |
500 MB/s |
600 MB/s |
1.2x |
| 随机读取(有 Bloom) |
200K ops/s |
400K ops/s |
2x |
| 写放大 |
15-30x |
4-10x |
3x |
| 空间放大 |
1.1x |
1.05x |
更小 |
⚠️ 注意:以上数据为典型场景下的近似值,实际性能取决于硬件、数据特征和配置参数。
14.4 RocksDB 独有特性详解
特性一:Column Family(列族)
// LevelDB:只能用前缀区分不同类型的数据
db->Put(wopts, "user:1001:name", "张三");
db->Put(wopts, "config:max_retry", "3");
// RocksDB:不同 Column Family 独立管理
rocksdb::ColumnFamilyHandle* user_cf;
rocksdb::ColumnFamilyHandle* config_cf;
db->CreateColumnFamily(rocksdb::ColumnFamilyOptions(), "user", &user_cf);
db->CreateColumnFamily(rocksdb::ColumnFamilyOptions(), "config", &config_cf);
db->Put(wopts, user_cf, "1001:name", "张三");
db->Put(wopts, config_cf, "max_retry", "3");
// 不同 CF 可以有不同的 Compaction 策略、压缩方式等
特性二:Universal Compaction
// LevelDB:只有 Level-based Compaction
// RocksDB:可以选择更写入友好的 Universal Compaction
rocksdb::Options options;
options.compaction_style = rocksdb::kCompactionStyleUniversal;
// Universal Compaction 特点:
// - 更低的写放大
// - 适合写入密集型场景
// - 空间放大会稍微增大
特性三:BlobDB(Value 分离存储)
// 场景:Value 很大(>1KB),不希望 Compaction 频繁移动
rocksdb::Options options;
options.enable_blob_files = true;
options.min_blob_size = 1024; // Value > 1KB 时分离存储
options.blob_file_size = 256 * 1024 * 1024; // Blob 文件大小
// 大 Value 存储在独立的 Blob 文件中
// Compaction 只移动 Key + Blob 引用,减少 I/O
特性四:Rate Limiter
// 限制 Compaction 的 I/O 带宽,避免影响前台读写
rocksdb::RateLimiter* rate_limiter = rocksdb::NewGenericRateLimiter(
100 * 1024 * 1024, // 100 MB/s
100000, // refill period (microseconds)
10, // fairness
rocksdb::RateLimiter::Mode::kWritesOnly
);
options.rate_limiter = rate_limiter;
特性五:Prefix Seek / Prefix Bloom
// LevelDB:前缀扫描需要手动检查
for (it->Seek(prefix); it->Valid() && it->key().starts_with(prefix); it->Next()) { ... }
// RocksDB:原生前缀 Bloom Filter 支持
rocksdb::Options options;
options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(8));
rocksdb::ReadOptions ropts;
ropts.prefix_same_as_start = true; // 只返回前缀匹配的结果
auto* it = db->NewIterator(ropts);
for (it->Seek(prefix); it->Valid(); it->Next()) { ... }
特性六:内置备份
// LevelDB:需要自己实现备份逻辑
// RocksDB:内置 BackupEngine
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngine::Open(
rocksdb::Env::Default(),
rocksdb::BackupEngineOptions("/backup/path"),
&backup_engine
);
// 创建备份
backup_engine->CreateNewBackup(db);
// 恢复备份
backup_engine->RestoreDBFromBackup(1, "/data/leveldb", rocksdb::RestoreOptions());
// 列出所有备份
std::vector<rocksdb::BackupInfo> backup_info;
backup_engine->GetBackupInfo(&backup_info);
14.5 迁移指南
API 对比
| 操作 |
LevelDB API |
RocksDB API |
| 打开 |
leveldb::DB::Open() |
rocksdb::DB::Open() |
| 写入 |
db->Put() |
db->Put() |
| 读取 |
db->Get() |
db->Get() |
| 删除 |
db->Delete() |
db->Delete() |
| 迭代器 |
db->NewIterator() |
db->NewIterator() |
| 批量写入 |
WriteBatch |
WriteBatch |
| 快照 |
GetSnapshot() |
GetSnapshot() |
| 头文件 |
leveldb/db.h |
rocksdb/db.h |
迁移步骤
步骤 1: 替换头文件
#include "leveldb/db.h" → #include "rocksdb/db.h"
步骤 2: 替换命名空间
leveldb::DB* → rocksdb::DB*
leveldb::Options → rocksdb::Options
leveldb::Status → rocksdb::Status
步骤 3: 替换库文件
-lleveldb → -lrocksdb
步骤 4: 数据格式兼容
LevelDB 的 SSTable 格式和 RocksDB 不直接兼容
需要重新导入数据
步骤 5: 测试
运行完整测试套件
CMake 迁移
# LevelDB
find_package(leveldb REQUIRED)
target_link_libraries(app leveldb::leveldb)
# RocksDB
find_package(RocksDB REQUIRED)
target_link_libraries(app RocksDB::rocksdb)
14.6 选型决策树
需要嵌入式 KV 存储吗?
├── 否 → 使用 etcd / TiKV / Redis
└── 是 → 数据量多大?
├── < 1GB
│ └── 读写性能要求?
│ ├── 普通 → LevelDB ✅
│ └── 高性能 → LevelDB(简单够用)
├── 1GB - 100GB
│ └── 并发写入?
│ ├── 单线程写 → LevelDB ✅
│ └── 多线程写 → RocksDB ✅
└── > 100GB
└── RocksDB ✅(更好的 Compaction、压缩、缓存)
选型建议
| 场景 |
推荐 |
原因 |
| 小型嵌入式应用 |
LevelDB |
简单、依赖少、久经考验 |
| 区块链节点 |
LevelDB / RocksDB |
LevelDB 足够(Bitcoin/Ethereum) |
| 分布式数据库底层 |
RocksDB |
多线程写、Column Family、更好的 Compaction |
| 时序数据库 |
RocksDB |
Universal Compaction、BlobDB |
| 配置存储 |
LevelDB |
简单可靠 |
| 日志/消息队列 |
LevelDB |
顺序写入简单高效 |
| 高吞吐写入 |
RocksDB |
多写者、Rate Limiter |
| 云原生部署 |
RocksDB |
Checkpoint 备份、远程 Compaction |
14.7 常见误区
误区一:“RocksDB 是 LevelDB 的超集,所以一定用 RocksDB”
事实:RocksDB 更复杂,配置选项更多,调优更难。
- LevelDB 的简单性是优势
- 对于小数据集、单线程场景,LevelDB 性能足够
- 过度配置 RocksDB 可能导致意想不到的问题
误区二:“LevelDB 已经不再维护”
事实:LevelDB 仍在维护(最后更新 2021 年),只是更新不频繁。
- Google 内部仍在使用
- Chromium、Bitcoin 等项目依赖 LevelDB
- 代码稳定是优势
误区三:“可以直接从 LevelDB 迁移到 RocksDB”
事实:SSTable 格式不兼容,不能直接复制数据文件。
迁移方式:
1. 导出数据 → 导入新数据库
2. 从 WAL 日志重建
3. 使用应用层复制
14.8 本章小结
| 维度 |
LevelDB |
RocksDB |
| 定位 |
简洁的嵌入式 KV 存储 |
高性能生产级 KV 存储 |
| 并发写 |
❌ |
✅ |
| Compaction |
Level-based |
Level/Universal/FIFO |
| 压缩 |
Snappy |
Snappy/Zlib/LZ4/ZSTD |
| 备份 |
自行实现 |
内置 BackupEngine |
| 学习曲线 |
低 |
中等 |
| 代码复杂度 |
~3万行 |
~20万行 |
| 活跃度 |
中等 |
非常活跃 |
| 许可证 |
BSD 3-Clause |
Apache 2.0 |
扩展阅读
- RocksDB Wiki:GitHub Wiki
- RocksDB 性能调优指南:Tuning Guide
- LevelDB vs RocksDB 对比论文:“Benchmarking LSM Key-Value Stores” (VLDB 2020)
- PebbleDB:CockroachDB 的 Go 实现 RocksDB 替代
← 第 13 章 · Docker 部署 | 第 15 章 · 生产最佳实践 →