RocksDB压缩策略 #
一、压缩概述 #
1.1 为什么需要压缩 #
text
压缩的作用:
├── 减少存储空间 - 降低磁盘占用
├── 减少IO开销 - 更少的数据读写
├── 提高缓存效率 - 更多数据进入缓存
└── 降低成本 - 减少存储和带宽成本
压缩的代价:
├── CPU开销 - 压缩/解压消耗CPU
├── 延迟增加 - 读写需要压缩/解压
└── 内存占用 - 解压需要临时内存
1.2 支持的压缩算法 #
| 算法 | 压缩比 | 压缩速度 | 解压速度 | 适用场景 |
|---|---|---|---|---|
| NoCompression | 1.0x | 最快 | 最快 | 临时数据、内存充足 |
| Snappy | ~2.0x | 很快 | 很快 | 实时数据、低延迟 |
| LZ4 | ~2.1x | 快 | 很快 | 平衡场景 |
| ZSTD | ~2.5-3.0x | 中等 | 快 | 存储密集型 |
| Zlib | ~2.5-3.5x | 慢 | 中等 | 存储优先 |
| BZip2 | ~3.0-4.0x | 很慢 | 慢 | 极致压缩 |
二、压缩配置 #
2.1 全局压缩配置 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <iostream>
int main() {
rocksdb::Options options;
options.create_if_missing = true;
// 设置全局压缩算法
options.compression = rocksdb::CompressionType::kLZ4Compression;
rocksdb::DB* db;
rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/testdb", &db);
if (status.ok()) {
std::cout << "Database opened with LZ4 compression" << std::endl;
}
delete db;
return 0;
}
2.2 分层压缩配置 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <vector>
rocksdb::Options GetLayeredCompressionOptions() {
rocksdb::Options options;
// 不同层级使用不同压缩算法
std::vector<rocksdb::CompressionType> compression_per_level = {
rocksdb::CompressionType::kNoCompression, // L0: 无压缩,写入快
rocksdb::CompressionType::kLZ4Compression, // L1: LZ4压缩
rocksdb::CompressionType::kLZ4Compression, // L2: LZ4压缩
rocksdb::CompressionType::kZSTD, // L3: ZSTD压缩
rocksdb::CompressionType::kZSTD, // L4: ZSTD压缩
rocksdb::CompressionType::kZSTD, // L5: ZSTD压缩
rocksdb::CompressionType::kZSTD // L6: ZSTD压缩
};
options.compression_per_level = compression_per_level;
return options;
}
2.3 压缩配置选项 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
rocksdb::Options GetCompressionOptions() {
rocksdb::Options options;
// 底层压缩(用于最底层)
options.bottommost_compression = rocksdb::CompressionType::kZSTD;
// 压缩选项
rocksdb::CompressionOptions compression_opts;
compression_opts.window_bits = -14; // ZSTD窗口大小
compression_opts.level = 3; // 压缩级别
compression_opts.strategy = 0; // 压缩策略
compression_opts.max_dict_bytes = 0; // 字典大小
compression_opts.zstd_max_train_bytes = 0;
compression_opts.enabled = true;
compression_opts.max_dict_buffer_bytes = 0;
options.compression_opts = compression_opts;
return options;
}
三、压缩算法详解 #
3.1 Snappy #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// Snappy - Google开发的高速压缩算法
// 特点:压缩速度快,解压更快,压缩比适中
// 适用:实时数据、低延迟场景
rocksdb::Options GetSnappyOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kSnappyCompression;
return options;
}
3.2 LZ4 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// LZ4 - 极速压缩算法
// 特点:压缩和解压都很快,压缩比略高于Snappy
// 适用:平衡压缩比和性能的场景
rocksdb::Options GetLZ4Options() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kLZ4Compression;
return options;
}
// LZ4HC - LZ4高压缩比版本
// 特点:压缩比更高,但压缩速度较慢
// 适用:写入不频繁,追求压缩比的场景
rocksdb::Options GetLZ4HCOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kLZ4HCCompression;
// 设置压缩级别(1-12,默认9)
options.compression_opts.level = 9;
return options;
}
3.3 ZSTD #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// ZSTD - Facebook开发的高效压缩算法
// 特点:压缩比高,速度适中
// 适用:存储密集型、冷数据
rocksdb::Options GetZSTDOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
// 设置压缩级别(1-22,默认3)
options.compression_opts.level = 3;
return options;
}
// 使用字典训练提高压缩比
rocksdb::Options GetZSTDDictOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
rocksdb::CompressionOptions compression_opts;
compression_opts.max_dict_bytes = 112640; // 字典大小
compression_opts.zstd_max_train_bytes = 1126400; // 训练数据大小
options.compression_opts = compression_opts;
return options;
}
3.4 Zlib #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// Zlib - 经典压缩算法
// 特点:压缩比高,速度较慢
// 适用:存储优先、写入不频繁
rocksdb::Options GetZlibOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZlibCompression;
// 设置压缩级别(1-9,默认-1表示默认级别)
options.compression_opts.level = 6;
return options;
}
四、压缩策略选择 #
4.1 按场景选择 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// 场景1:实时交易系统 - 低延迟优先
rocksdb::Options GetRealtimeOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kSnappyCompression;
return options;
}
// 场景2:日志存储 - 存储优先
rocksdb::Options GetLogStorageOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
options.compression_opts.level = 9;
return options;
}
// 场景3:混合场景 - 平衡配置
rocksdb::Options GetBalancedOptions() {
rocksdb::Options options;
// L0-L2: 快速压缩
// L3+: 高压缩比
options.compression_per_level = {
rocksdb::CompressionType::kNoCompression,
rocksdb::CompressionType::kLZ4Compression,
rocksdb::CompressionType::kLZ4Compression,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD
};
return options;
}
// 场景4:时序数据 - 分层压缩
rocksdb::Options GetTimeSeriesOptions() {
rocksdb::Options options;
// 新数据(L0-L1): 快速压缩
// 旧数据(L2+): 高压缩比
options.compression_per_level = {
rocksdb::CompressionType::kLZ4Compression,
rocksdb::CompressionType::kLZ4Compression,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD,
rocksdb::CompressionType::kZSTD
};
// 底层使用最高压缩
options.bottommost_compression = rocksdb::CompressionType::kZSTD;
return options;
}
4.2 性能测试对比 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <chrono>
#include <iostream>
void BenchmarkCompression(rocksdb::CompressionType compression,
const std::string& name,
int num_records) {
std::string db_path = "/tmp/bench_" + name;
rocksdb::Options options;
options.create_if_missing = true;
options.compression = compression;
rocksdb::DB* db;
rocksdb::DB::Open(options, db_path, &db);
// 写入测试
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < num_records; i++) {
std::string key = "key_" + std::to_string(i);
std::string value(1000, 'x'); // 1KB数据
db->Put(rocksdb::WriteOptions(), key, value);
}
auto write_end = std::chrono::high_resolution_clock::now();
// 读取测试
std::string value;
for (int i = 0; i < num_records; i++) {
std::string key = "key_" + std::to_string(i);
db->Get(rocksdb::ReadOptions(), key, &value);
}
auto read_end = std::chrono::high_resolution_clock::now();
// 获取数据库大小
uint64_t db_size = 0;
db->GetIntProperty("rocksdb.total-sst-files-size", &db_size);
// 输出结果
auto write_ms = std::chrono::duration_cast<std::chrono::milliseconds>(write_end - start).count();
auto read_ms = std::chrono::duration_cast<std::chrono::milliseconds>(read_end - write_end).count();
std::cout << name << ":" << std::endl;
std::cout << " Write: " << write_ms << " ms" << std::endl;
std::cout << " Read: " << read_ms << " ms" << std::endl;
std::cout << " Size: " << db_size / 1024 / 1024 << " MB" << std::endl;
delete db;
}
五、压缩与Compaction #
5.1 压缩在Compaction中的作用 #
text
Compaction流程中的压缩:
数据写入 → MemTable → Flush → L0 SST (无压缩/轻压缩)
↓
Compaction
↓
L1 SST (LZ4压缩)
↓
Compaction
↓
L2+ SST (ZSTD压缩)
5.2 底层压缩优化 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
// 底层压缩配置
rocksdb::Options GetBottommostCompressionOptions() {
rocksdb::Options options;
// 普通层级压缩
options.compression = rocksdb::CompressionType::kLZ4Compression;
// 底层(最老数据)使用最高压缩
options.bottommost_compression = rocksdb::CompressionType::kZSTD;
// 底层压缩选项
rocksdb::CompressionOptions bottommost_opts;
bottommost_opts.level = 19; // ZSTD最高压缩级别
options.bottommost_compression_opts = bottommost_opts;
return options;
}
六、压缩统计 #
6.1 获取压缩统计信息 #
cpp
#include <rocksdb/db.h>
#include <iostream>
void PrintCompressionStats(rocksdb::DB* db) {
uint64_t total_sst_size = 0;
uint64_t uncompressed_size = 0;
db->GetIntProperty("rocksdb.total-sst-files-size", &total_sst_size);
db->GetIntProperty("rocksdb.estimate-num-keys", &uncompressed_size);
std::cout << "Compression Statistics:" << std::endl;
std::cout << " Total SST size: " << total_sst_size / 1024 / 1024 << " MB" << std::endl;
// 各层压缩统计
for (int level = 0; level < 7; level++) {
uint64_t level_size = 0;
std::string prop = "rocksdb.compression-ratio-at-level" + std::to_string(level);
// 注意:需要启用统计
std::cout << " Level " << level << " size: " << level_size << std::endl;
}
}
七、最佳实践 #
7.1 压缩策略建议 #
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 实时交易 | Snappy/LZ4 | 低延迟优先 |
| 日志存储 | ZSTD | 存储优先 |
| 时序数据 | 分层压缩 | 新数据快压缩,旧数据高压缩 |
| 缓存数据 | 无压缩 | 减少CPU开销 |
| 混合场景 | LZ4 + ZSTD分层 | 平衡性能和存储 |
7.2 压缩级别选择 #
cpp
// 压缩级别权衡:
// - 级别越高,压缩比越大,但压缩速度越慢
// - 解压速度通常与级别无关
// ZSTD级别建议:
// 1-3: 快速压缩,适合热数据
// 4-9: 平衡压缩,适合温数据
// 10-22: 高压缩比,适合冷数据
rocksdb::Options GetZSTDFastOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
options.compression_opts.level = 1; // 快速压缩
return options;
}
rocksdb::Options GetZSTDBalancedOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
options.compression_opts.level = 3; // 默认级别
return options;
}
rocksdb::Options GetZSTDMaxOptions() {
rocksdb::Options options;
options.compression = rocksdb::CompressionType::kZSTD;
options.compression_opts.level = 19; // 最高压缩
return options;
}
八、总结 #
8.1 压缩算法对比 #
| 算法 | 压缩比 | 速度 | 推荐场景 |
|---|---|---|---|
| NoCompression | 1.0x | 最快 | 临时数据 |
| Snappy | ~2.0x | 很快 | 实时数据 |
| LZ4 | ~2.1x | 快 | 平衡场景 |
| ZSTD | ~2.5x | 中等 | 存储密集 |
| Zlib | ~3.0x | 慢 | 极致压缩 |
8.2 关键要点 #
- 按场景选择:根据延迟和存储需求选择算法
- 分层压缩:不同层级使用不同压缩
- 底层优化:最老数据使用最高压缩
- 监控效果:关注压缩比和性能影响
- 测试验证:实际场景测试选择最优配置
下一步,让我们学习合并操作!
最后更新:2026-03-27