LSM Tree 的 Compaction 策略
LSM Tree 的数据不更新,只追加。旧数据会一直占用空间,需要定期「合并清理」。这个过程叫 Compaction。
Compaction 是 LSM Tree 最复杂的部分,也是调优的重点。
为什么需要 Compaction
LSM Tree 的写入是追加的,同一个 key 可能有多份副本:
问题:
- 空间浪费:同一 key 多份副本,占用额外空间
- 读放大:查询需要检查多层
Compaction 就是把重复的 key 合并,只保留最新值。
Compaction 策略分类
Leveled Compaction
Leveled Compaction 把数据分层,每层容量指数增长:
每层只包含有序的、无重复 key 的 SSTable。
Leveled Compaction 流程
Size-Tiered Compaction
Size-Tiered 不分层,按文件大小组织:
当某个 Tier 的文件数量达到阈值,触发合并:
两种策略对比
写放大计算(Leveled):
Compaction 的代价
磁盘 I/O 风暴
Compaction 是重操作,会消耗大量磁盘 I/O:
写入速率影响
Compaction 会和正常写入竞争磁盘带宽:
Compaction 调优参数
RocksDB Compaction 配置
常见问题与调优
写入抖动严重?
读取延迟高?
空间不足?
选择 Compaction 策略
选择 Leveled Compaction:
- 对空间放大敏感(存储成本高)
- 写入速率平稳
- 读取延迟要求低
选择 Size-Tiered Compaction:
- 写入突增场景
- 写放大敏感
- 可以容忍稍高的空间放大
经验之谈:大多数场景下,Leveled Compaction 是更好的选择。但如果你的场景是「写入为主、偶尔大量删除」,Size-Tiered 可能更合适。生产环境建议先用 Leveled,观察一段时间后再根据实际情况调整。