Write Stall 介绍

上图是简单来说就是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
- 触发 write stall 的 L0 文件最大个数。
- v8.5.4 及之前版本:当开启流控机制(storage.flow-control.enable 为 true)时,该配置项会被 storage.flow-control.l0-files-threshold 直接覆盖。
- 从 v8.5.5 起:当开启流控机制(storage.flow-control.enable 为 true)时,该配置项仅在其值大于 storage.flow-control.l0-files-threshold 时会被 storage.flow-control.l0-files-threshold 覆盖,以避免在调大流控阈值时削弱 RocksDB 的 compaction 加速机制。
- 默认值:20
- 最小值:0
soft-pending-compaction-bytes-limit
- pending compaction bytes 的软限制。
- v8.5.4 及之前版本:当开启流控机制(storage.flow-control.enable 为 true)时,该配置项会被 storage.flow-control.soft-pending-compaction-bytes-limit 直接覆盖。
- 从 v8.5.5 起:当开启流控机制(storage.flow-control.enable 为 true)时,该配置项仅在其值大于 storage.flow-control.soft-pending-compaction-bytes-limit 时会被 storage.flow-control.soft-pending-compaction-bytes-limit 覆盖,以避免在调大流控阈值时削弱 RocksDB 的 compaction 加速机制。
- 默认值:192GiB
- 单位:KiB|MiB|GiB