SQL TiDB 的 TiKV compaction 的 level 与 write stall 缓解

2次阅读

tikv 的 compaction level 不直接触发 write stall,但层级结构(l0–l6)影响 compaction 效率:l0 文件过多或中高层数据膨胀会加剧 compact backlog,进而通过 memtable 超限、l0 文件数超限、pending compaction bytes 过高三类条件引发 write stall;调优应聚焦提前触发 l0 compact、增加后台并发、监控各层文件数与 pending 状态,并协同硬件与部署优化。

SQL TiDB 的 TiKV compaction 的 level 与 write stall 缓解

TiKV 的 compaction level 本身不直接控制 write stall,但 compaction 效率和调度策略会显著影响 write stall 的触发频率和持续时间。关键在于理解 level(层级)在 LSM-tree 中的角色,以及它如何与写入压力、资源瓶颈和 TiKV 的限流机制交互。

Level 结构如何影响 compaction 压力

TiKV 使用 RocksDB 作为底层存储引擎,其默认采用多级 LSM-tree(Level-based Compaction),共 7 级(L0–L6)。L0 层由 MemTable flush 生成,文件无序且允许重叠;L1 及以上每层数据有序、文件不重叠,且大小逐级指数增长(如 L1 ≈ 256MB,L2 ≈ 2GB,L3 ≈ 16GB…)。

这种设计意味着:

  • L0 文件过多(如 >4,由 level0_file_num_compaction_trigger 控制)会快速触发 L0→L1 compaction,而 L0 文件读放大高、compact 开销大,容易抢占 I/O 和 CPU 资源
  • L1–L6 某一层数据量膨胀(如 L3 实际大小远超理论目标),会导致该层 compact backlog 积压,进而阻塞上游 flush 和写入
  • 如果某层 compact 速度持续低于写入速度(例如磁盘吞吐不足或 CPU 不足),整个 compaction pipeline 就会“淤塞”,最终触发 write stall

Write stall 的三类触发条件及其与 level 的关联

TiKV(RocksDB)的 write stall 主要由以下三种 condition 触发,每种都和 level 状态强相关:

  • MemTable 数量超限:当未 flush 的 MemTable 达到 max_write_buffer_number(默认 5),写入被 stall。这反映 L0 flush 太慢——可能因 L0→L1 compact 慢,导致 L0 文件积,反过来又拖慢新 MemTable flush
  • L0 文件数超限:L0 文件数 ≥ level0_file_num_compaction_trigger(默认 4)时,强制触发 L0 compact;若此时 compact 无法及时完成,系统会 stall 写入等待 compact 进度
  • Pending compaction bytes 过高:当待 compact 数据量 ≥ soft_pending_compaction_bytes_limit(默认 64GB)时进入 soft stall(限速写入);≥ hard_pending_compaction_bytes_limit(默认 256GB)则硬 stall(完全阻塞)。这个指标直接受各 level 数据膨胀程度影响

缓解 write stall 的实用调优方向(聚焦 level 相关参数)

不建议盲目调高 level 数或修改 level 目标大小,而应优先保障 compaction 吞吐能力,并让 level 增长更平滑:

  • 调低 level0_file_num_compaction_trigger(如设为 2–3):让 L0 compact 更早启动,避免 L0 文件爆发式堆积,降低单次 compact 压力
  • 适当增大 max_background_jobs(如从默认 4 提至 8):提升并发 compact 线程数,尤其利于 L0→L1 和中层 compact 并行处理
  • 启用 universal-compaction(仅限特定场景):对写密集、key 分布倾斜明显的业务,Universal 可减少 L0 堆积和写放大,但会提高读放大,需实测验证
  • 监控 rocksdb/cur_size_active_mem_tablerocksdb/num-files-at-levelrocksdb/compaction-pending 等指标:确认是否某一层(如 L2 或 L3)长期处于“鼓包”状态,针对性调整该层 size ratio 或增加 level0_slowdown_writes_trigger

硬件与部署协同优化不可忽视

再合理的 level 策略也受限于底层资源:

  • SSD 必须使用高性能 NVMe,避免 SATA SSD 成为 compaction I/O 瓶颈
  • TiKV 实例应独占 CPU 核心,避免与其他服务混部导致 compaction 线程被调度饥饿
  • 开启 background_gc(TiKV v6.1+ 默认开启)可异步清理过期 MVCC 版本,间接减少 compact 需处理的数据量
  • Region 数量过多(如单节点 >10k)会加剧 Raft log 和 KV 引擎间协调开销,放大 compaction 延迟效应,需配合 PD 调度策略控制 Region 均衡
text=ZqhQzanResources