0
0
0
0
博客/.../

写流控 Write Stall

 克里克里克  发表于  2026-08-22

Write Stall 介绍

0

上图是简单来说就是tidb集群写入数据的流程,在整个环节内涉及到了memtable写L0,L0合并至L1,L1-Ln层的数据合并,如果其中某一个环节有积压,就会触发“Write Stall”流控机制,限制上游的写入流量或者限制写入,从而导致业务层面反馈系统慢或者无响应。

经过版本不断优化迭代,TiDB逐渐将RocksDB 的 write stall 机制替代为在 scheduler 层进行流量控制。以避免 write stall 机制卡住 Raftstore 或 Apply 线程导致的次生问题。

如下将针对新旧两种Write Stall参数进行介绍。

Scheduler层流控

在6.0+版本之后默认启用,由tikv层参数storage.flow-control.enable控制是否开启。

memtable层

rocksdb.defaultcf.min-write-buffer-number-to-merge:触发flush的最小memtableg额数;

rocksdb.defaultcf.write-buffer-size:defaultcf列簇的memtable大小,默认128M,每个列簇大小不同,超过该大小,继续新写一个memtable,转储该memtable内存信息至L0层。

rocksdb.max-background-flushes:RocksDB 用于刷写 memtable 的最大后台线程数量,CPU 核数为 N 时,默认值为 [(max-background-jobs + 3) / 4]。

storage.flow-control.memtables-threshold:默认为5,当 KvDB 的 待刷新到磁盘的memtable 的个数达到该阈值时,流控机制开始工作。当 enable 的值为 true 时,会覆盖 rocksdb.(defaultcf|writecf|lockcf).max-write-buffer-number 的配置。

L0层

rocksdb.defaultcf.level0-file-num-compaction-trigger:触发 compaction 的 L0 文件最大个数,L0层达到该值将与L1层的sst文件进行compaction;

storage.flow-control.l0-files-threshold:默认20,当 KvDB 的待合并的 L0 文件个数达到该阈值时,流控机制开始工作。当满足一定条件时,rocksdb.(defaultcf|writecf|lockcf|raftcf).level0-slowdown-writes-trigger 的值会被该配置项覆盖。详情参考 rocksdb.(defaultcf|writecf|lockcf|raftcf).level0-slowdown-writes-trigger。

L1-Ln层

rocksdb.defaultcf.max-bytes-for-level-base:默认512M,level1的数据量大小达到该值,会触发level1的sst和level2中的sst进行compaction;

storage.flow-control.soft-pending-compaction-bytes-limit:默认192G,软限制,当pending compaction bytes到达该值拒绝部分写入请求,报Server Is Busy;

storage.flow-control.hard-pending-compaction-bytes-limit:默认1T,硬限制,当L1-Ln层待compaction的数据达到该值,拒绝所有写入请求;

rocksdb.max-background-jobs:CPU核数>10时,默认为9,CPU 核数为 N 时,默认值为 max(2, min(N - 1, 9)),RocksDB后台线程个数,增加该值可以加速L1-Ln层compaction的处理速度。

RocksDB层流控

当storage.flow-control.enable=false时,启用原生的Write Stall。

memtable

max-write-buffer-number:最多允许几个memtable存在,默认5个,等待写入的immutable超过5个进入流控,禁止写入,flow-control启用后,该参数被代替。

其余memtable层参数同《Scheduler层流控》。

L0层

rocksdb.level0-file-num-compaction-trigger;

rocksdb.defaultcf.level0-slowdown-writes-trigger:当level0的sst文件到达该参数指定限度时,RocksDB尝试减缓写入速度,默认20,level0的sst太多也会导致读放大上升,flow-control启用后,该参数被storage.flow-control.l0-files-threshold替代;

rocksdb.defaultcf.level0-stop-writes-trigger:当level0的sst文件达到该值,会停止写入,默认36;

rocksdb.max-sub-compactions:是单个 compaction 任务的子任务并发数,默认3,加速L0层过多sst文件的compaction;

L1-Ln层

rocksdb.defaultcf.max-bytes-for-level-base;

rocksdb.defaultcf.soft-pending-compaction-bytes-limit:默认192G,当pending compaction bytes到达该值拒绝部分写入请求,报Server Is Busy;

rocksdb.defaultcf.hard-pending-compaction-bytes-limit:默认1024G,到达该值拒绝所有写入请求;

rocksdb.max-background-jobs;

判断出现Write Stall

Scheduler流控-TiKV-Details-Flow Control-

Scheduler discard ratio:每个 TiKV 实例的 scheduler 的请求拒绝比率。如果该比例大于 0,则表明存在流控。当 Compaction pending bytes 超过阈值时,TiKV 会根据超过阈值部分的值,按比例线性增加 Scheduler discard ratio。被拒绝的请求将自动由客户端重试;

Throttle duration:L0 文件过多并触发流控后,scheduler 执行请求的阻塞时间。如果存在统计数据,则表明存在流控;

Scheduler throttled CF:由于达到流控阈值,触发 RocksDB 限流的 CF;

Flow controller actions:由于达到流控阈值,触发 RocksDB 限流的原因;

Flow control factors:触发 RocksDB 限流相关的因素;

Compaction pending bytes:每个 TiKV 实例上 RocksDB 实时等待 compaction 的数据的大小;

流控的处理方案

应急措施:查看是哪一层触发的流控,在机器资源未达瓶颈时临时调大相关的参数。

根本方案:需要查看拆分大事务、提升硬件或者扩容tikv、避免写热点集中。

补充

storage.scheduler-pending-write-threshold:默认100M,写入数据队列的最大值,超过该值之后对于新的写入 TiKV 会返回 Server Is Busy 错误

8.5.5+版本后参数变更:

level0-slowdown-writes-trigger

soft-pending-compaction-bytes-limit

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论