RocksDB Compaction #
一、Compaction概述 #
1.1 什么是Compaction #
Compaction是RocksDB的核心维护机制,负责合并SST文件、清理无效数据和优化存储。
text
Compaction的作用:
├── 合并文件 - 将多个SST文件合并
├── 清理数据 - 删除无效的键值对
├── 降低放大 - 减少读放大和空间放大
├── 数据重组 - 优化数据布局
└── 应用压缩 - 对数据进行压缩
1.2 为什么需要Compaction #
text
没有Compaction的问题:
1. 文件数量增长
- L0文件越来越多
- 查找需要检查所有文件
2. 空间浪费
- 旧版本数据未清理
- 已删除数据占用空间
3. 读性能下降
- 多层查找
- 文件数量多
Compaction解决:
- 定期合并文件
- 清理无效数据
- 优化存储结构
二、Compaction类型 #
2.1 Leveled Compaction(默认) #
text
Leveled Compaction流程:
Level N → Level N+1
L0: [a-d] [c-f] [e-h] (文件可能重叠)
↓ Compaction
L1: [a-c] [d-f] [g-i] (文件不重叠)
特点:
- 每层大小固定倍数增长
- 文件不重叠
- 写放大较高
- 读放大较低
2.2 Tiered Compaction #
text
Tiered Compaction流程:
Level N文件累积到一定数量后合并
L0: [file1] [file2] [file3] [file4]
↓ 累积后合并
L1: [merged_file]
特点:
- 批量合并
- 写放大较低
- 读放大较高
- 空间放大较高
2.3 FIFO Compaction #
text
FIFO Compaction流程:
先进先出,旧数据自动删除
[oldest] → [older] → [newer] → [newest]
↓
删除
特点:
- 适合时序数据
- 自动清理旧数据
- 写放大最低
- 不支持更新删除
2.4 Compaction类型对比 #
| 类型 | 写放大 | 读放大 | 空间放大 | 适用场景 |
|---|---|---|---|---|
| Leveled | 高 | 低 | 低 | 通用场景 |
| Tiered | 低 | 高 | 高 | 写密集型 |
| FIFO | 最低 | 低 | 最低 | 时序数据 |
三、Leveled Compaction详解 #
3.1 触发条件 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetCompactionOptions() {
rocksdb::Options options;
// L0文件数量触发
options.level0_file_num_compaction_trigger = 4;
// L0文件数量触发写入减速
options.level0_slowdown_writes_trigger = 20;
// L0文件数量触发写入停止
options.level0_stop_writes_trigger = 36;
// 层级大小触发
options.max_bytes_for_level_base = 256 * 1024 * 1024; // 256MB
options.max_bytes_for_level_multiplier = 10;
return options;
}
3.2 Compaction过程 #
text
Leveled Compaction过程:
1. 选择Compaction文件
│
▼
2. 确定输入文件
│ - Level N的选中文件
│ - Level N+1的重叠文件
▼
3. 多路归并排序
│ - 创建Iterator
│ - 合并排序
▼
4. 生成新SST文件
│ - 写入Level N+1
│ - 应用压缩
▼
5. 原子更新Version
│ - 添加新文件
│ - 删除旧文件
▼
6. 完成
3.3 文件选择策略 #
text
文件选择策略:
1. 优先级计算
- 文件大小
- 删除数据比例
- 读取频率
2. L0选择
- 选择最旧的文件
- 可能选择多个文件
3. Ln选择
- 选择超过层级大小限制的文件
- 考虑文件间的重叠
四、Compaction配置 #
4.1 基本配置 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetCompactionConfig() {
rocksdb::Options options;
// Compaction风格
options.compaction_style = rocksdb::CompactionStyle::kCompactionStyleLevel;
// 后台Compaction线程数
options.max_background_compactions = 4;
options.max_background_jobs = 8;
// Compaction触发阈值
options.level0_file_num_compaction_trigger = 4;
// 层级大小配置
options.max_bytes_for_level_base = 256 * 1024 * 1024;
options.max_bytes_for_level_multiplier = 10;
return options;
}
4.2 高级配置 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetAdvancedCompactionConfig() {
rocksdb::Options options;
// Compaction优先级
options.compaction_pri = rocksdb::CompactionPri::kByCompensatedSize;
// 目标文件大小
options.target_file_size_base = 64 * 1024 * 1024; // 64MB
options.target_file_size_multiplier = 1;
// 最大Compaction字节数
options.max_compaction_bytes = 256 * 1024 * 1024;
// 软链接Compaction
options.soft_pending_compaction_bytes_limit = 64 * 1024 * 1024 * 1024;
options.hard_pending_compaction_bytes_limit = 256 * 1024 * 1024 * 1024;
return options;
}
4.3 压缩配置 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetCompressionConfig() {
rocksdb::Options options;
// 分层压缩
options.compression_per_level = {
rocksdb::CompressionType::kNoCompression, // L0
rocksdb::CompressionType::kLZ4Compression, // L1
rocksdb::CompressionType::kLZ4Compression, // L2
rocksdb::CompressionType::kZSTD, // L3
rocksdb::CompressionType::kZSTD, // L4
rocksdb::CompressionType::kZSTD, // L5
rocksdb::CompressionType::kZSTD // L6
};
// 底层压缩
options.bottommost_compression = rocksdb::CompressionType::kZSTD;
return options;
}
五、手动Compaction #
5.1 CompactRange #
cpp
#include <rocksdb/db.h>
#include <rocksdb/options.h>
void ManualCompaction(rocksdb::DB* db) {
rocksdb::CompactRangeOptions options;
// 等待Compaction完成
options.exclusive_manual_compaction = true;
// 压缩到最底层
options.bottommost_level_compaction =
rocksdb::BottommostLevelCompaction::kForce;
// 对整个数据库执行Compaction
rocksdb::Status status = db->CompactRange(options, nullptr, nullptr);
if (status.ok()) {
std::cout << "Manual compaction completed!" << std::endl;
}
}
// 对指定范围执行Compaction
void CompactRange(rocksdb::DB* db,
const std::string& start,
const std::string& end) {
rocksdb::CompactRangeOptions options;
rocksdb::Slice start_slice(start);
rocksdb::Slice end_slice(end);
db->CompactRange(options, &start_slice, &end_slice);
}
5.2 CompactFiles #
cpp
#include <rocksdb/db.h>
#include <vector>
void CompactSpecificFiles(rocksdb::DB* db,
int level,
const std::vector<std::string>& file_names) {
rocksdb::CompactionOptions options;
options.compression = rocksdb::CompressionType::kZSTD;
options.output_file_size_limit = 64 * 1024 * 1024;
rocksdb::Status status = db->CompactFiles(options, file_names, level + 1);
if (status.ok()) {
std::cout << "Files compacted successfully!" << std::endl;
}
}
六、Compaction监控 #
6.1 监控指标 #
cpp
#include <rocksdb/db.h>
#include <iostream>
void PrintCompactionStats(rocksdb::DB* db) {
uint64_t value;
// 待Compaction字节数
db->GetIntProperty("rocksdb.estimate-pending-compaction-bytes", &value);
std::cout << "Pending compaction: " << value / 1024 / 1024 << " MB" << std::endl;
// 正在进行的Compaction数量
db->GetIntProperty("rocksdb.num-running-compactions", &value);
std::cout << "Running compactions: " << value << std::endl;
// 各层文件数量
for (int level = 0; level < 7; level++) {
std::string prop = "rocksdb.num-files-at-level" + std::to_string(level);
db->GetIntProperty(prop, &value);
std::cout << "Level " << level << " files: " << value << std::endl;
}
}
6.2 Compaction统计 #
cpp
#include <rocksdb/statistics.h>
void PrintCompactionStatistics(rocksdb::DB* db) {
auto stats = db->GetOptions().statistics;
// Compaction写入字节数
uint64_t bytes_written = stats->getTickerCount(rocksdb::COMPACT_WRITE_BYTES);
std::cout << "Compaction write: " << bytes_written / 1024 / 1024 << " MB" << std::endl;
// Compaction读取字节数
uint64_t bytes_read = stats->getTickerCount(rocksdb::COMPACT_READ_BYTES);
std::cout << "Compaction read: " << bytes_read / 1024 / 1024 << " MB" << std::endl;
// Compaction次数
uint64_t count = stats->getTickerCount(rocksdb::NUMBER_DB_NEXT);
std::cout << "Compaction count: " << count << std::endl;
}
七、Compaction优化 #
7.1 性能优化 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetOptimizedCompactionOptions() {
rocksdb::Options options;
// 增加后台线程
options.max_background_compactions = 8;
options.max_background_jobs = 16;
// 调整触发阈值
options.level0_file_num_compaction_trigger = 8;
// 增大层级大小
options.max_bytes_for_level_base = 512 * 1024 * 1024;
// 调整目标文件大小
options.target_file_size_base = 128 * 1024 * 1024;
return options;
}
7.2 写放大优化 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetWriteAmplificationOptimized() {
rocksdb::Options options;
// 使用Tiered Compaction
options.compaction_style = rocksdb::CompactionStyle::kCompactionStyleUniversal;
// Tiered Compaction配置
options.level0_file_num_compaction_trigger = 4;
options.level0_layer_size_compaction_trigger = 2;
return options;
}
7.3 空间优化 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetSpaceOptimized() {
rocksdb::Options options;
// 使用Leveled Compaction
options.compaction_style = rocksdb::CompactionStyle::kCompactionStyleLevel;
// 更频繁的Compaction
options.level0_file_num_compaction_trigger = 2;
// 启用压缩
options.compression = rocksdb::CompressionType::kZSTD;
return options;
}
八、Compaction最佳实践 #
8.1 场景配置 #
| 场景 | Compaction风格 | 配置建议 |
|---|---|---|
| 通用场景 | Leveled | 默认配置 |
| 写密集型 | Tiered | 减少写放大 |
| 时序数据 | FIFO | 自动清理旧数据 |
| 读密集型 | Leveled | 减少读放大 |
8.2 调优建议 #
- 监控Compaction状态:关注待Compaction字节数
- 合理设置线程数:根据CPU核心数配置
- 调整触发阈值:平衡写入和Compaction
- 选择压缩算法:平衡压缩比和CPU开销
- 定期手动Compaction:优化特定范围
九、总结 #
9.1 Compaction关键参数 #
| 参数 | 说明 |
|---|---|
| compaction_style | Compaction风格 |
| max_background_compactions | 后台线程数 |
| level0_file_num_compaction_trigger | L0触发阈值 |
| max_bytes_for_level_base | 层级基础大小 |
9.2 关键要点 #
- 核心机制:Compaction是LSM-Tree的核心维护机制
- 类型选择:根据场景选择合适的Compaction类型
- 配置优化:合理配置触发条件和线程数
- 监控管理:关注Compaction状态和性能
- 手动干预:必要时手动触发Compaction
RocksDB文档系列完成!
最后更新:2026-03-27