TiKV 主要内存结构和 OOM 排查总结
作者: h5n1 原文来源:https://tidb.net/blog/ab528ebf
·
1 tikv 主要内存
1.1 block cache
TiKV 底层使用 rocskdb 作为存储引擎,block cache 用于缓存从 sst 文件读取的 block,采用 LRU 方式管理。TiKV 底层包含 2 个 rocksdb 实例一个用于存储 raftlog 叫 raftdb(参数中为 raftdb),仅包含一个 default CF 。另一个存储实际数据和锁信息叫 kvdb(参数中为 rocksdb), 包含 default、write、lock、raft 4 个 CF。每个 CF 可通过相应的 block-cache-size 参数调整大小,当设置 storage.block-cache.shared=true 时 2 个 rocksdb 实例会中所有 CF 使用共享的 block cache 区域,自动调整每个 CF 使用的内存大小。通过参数 storage.block-cache.capacity 设置这个共享区的大小,默认为内存的 45%,该参数并非硬限制,会出现实际使用内存超出参数设置大小的情况。
1.2 write buffer
1.3 raftstore
当 apply 速度慢时则会导致 entry cache 内条目堆积,cache 不断增长,当达到系统内存的 evict-cache-on-memory-ratio 比例 (默认 0.2) 时则会 evtict entry cache,如果待 apply 的 log 没有在 cache 内则会从 ratdb 内读取 raftlog,这样会增加 apply 的延迟。
1.4 Coprocessor & gRPC
TiDB 会构建 coprocessor task 下发到 tikv, 由 unified-pool 中线程完成 ( 5.0 版本后),每个 cop task 处理 1 个 region 的数据,之后将读取的数据或中间结果以 gRPC response 形式放入内存,等待 gRPC 向 tidb 返回。如果 gRPC 的发送速度慢于 coprocessor 数据的产生速度会导致大量内存占用,gRPC 发送慢可能是 gRPC 线程出现瓶颈或网络出现问题。
Tikv 内可通过 server.max-grpc-send-msg-len 参数控制发送的消息最大大小,server.grpc-memory-pool-quota 控制 gRPC 能够使用的内存大小,目前无限制,调低 gRPC 内存可能引起性能降低或其他问题。
1.5 transaction
1.6 CDC
在 TiKV 侧有 cdc component 组件用于跟踪 tikv 的变化和向下游 ticdc 发送数据,可通过参数 cdc.old-value-cache-memory-quota 控制 old value 缓存的大小,cdc.sink-memory-quota 控制缓存在 tikv 中等待下发的 cdc change event 所占的内存大小。
1.7 BR
BR 备份时会读取 region 数据到 tikv 内存中然后由 sst writer 写出,若果存在 huge region 则可能会占用大量内存导致 oom。
1.8 tikv 内存上限
memory-usage-high-water 参数控制 tikv 内存上限,默认为系统内存的 90%。
2 确认 oom
1、 检查 tikv 相关监控 ,如 uptime 、leader、memory 等是否出现掉零情况。
2、 检查 tikv.log 中 Weclom 关键字。
3、 检查操作系统日志是否出现 oom。
3 TiKV OOM 排查
3.1 检查内存使用
监控:TiKV Detail -> Clusters -> Memory
3.2 检查 block cache
监控:TiKV Detail -> RocksDB KV -> Block cache size
使用的大小和 block cache 参数,确认实际使用大小是否超过参数设置值,如果 block cache 超过参数设置大小则说明有大量的大查询。
3.3 检查 write buffer
检查大小和最大数量设置是否过大,是否出现因 memtable 导致的 write stall, 如果 memtable 设置过大出现 write stall 时则占用大量内存。
监控:TiKV Detail -> RocksDB KV -> Write Stall Reason
write buffer 大量积压可检查是否存在磁盘问题导致 flush 速度较慢。
3.4 检查 coprocessor 是否积压
TiKV Detail -> Coprocessor Overview -> Total Response Size ,该监控表示 所有 tikv 上 coprocessor 向上层返回 response 的大小。
Node_exporter -> Network -> Network IN/OUT Traffice -> Outbound 指标,使用该监控检查每个 tikv 节点的出站流量。
TiKV Detail -> Thread CPU -> gRPC poll CPU,检查 gRPC 线程是否繁忙。
如果所有 TiKV 的出站流量之和比 response 速度小很多则说明 coprocessor 数据有积压。如果 gRPC CPU 线程存在瓶颈可考虑增加 gRPC 线程数。
网络问题可通过 Node_expoter/Black_exporter 监控查看。
3.5 检查 raft store 内存占用
3.6 检查 apply 延迟和线程繁忙度
3.7 检查 CDC
检查 TikV 侧 CDC 模块中 oldvalue、sink 使用的内存参数设置和实际使用大小
监控:TiCDC -> TiKV -> CDC memory
3.8 检查是否有 Huge Region
监控:TiKV-Trouble-Shooting -> Huge Region
可通过 TIKV_REGION_STATUS 表或 pd-ctl region 查看 top size region。
3.9 检查透明大页是否关闭
正在运行中的系统可通过 /sys/kernel/mm/transparent_hugepage/enabled,/sys/kernel/mm/transparent_hugepage/defrag 文件内容检查是否启用了 THP,如为 never 则表示已禁用。
建议通过 grub.conf 添加 transparent_hugepage=never 方式在内核禁用 THP,相关可参考文档https://access.redhat.com/solutions/46111
3.10 检查 numa 设置
(1) 检查 numa node 数量和每个 Node 的内存大小: numactl -H
(2) 检查是否绑定 Numa_node(tiup cluster edit-config 检查或部署目录 scripts 下的 run_xxxx.sh 脚本),tikv 相关内存参数设置是否超过 numa node 的内存大小
(3) TiDB 内未绑定 numa 时检查默认策略: numactl –show,常见策略内存分配:
strict/default: 仅在进程运行的 Numa node 上分配内存
interleave: 在所有的 numa node 上交叉分配
preferred: 在进程运行的 numa node 上分配,不足时在去其他 node 分配。
3.11 检查是否设置资源限制
参考文档:
https://pingcap.com/zh/blog/tikv-source-code-reading-17
https://github.com/tikv/tikv/issues/1418 raft: cache raft log to avoid getting from rocksdb #1418
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/eb4e712e60dda87515c4b5228】。文章转载请联系作者。
评论