Day18
如何处理数据热点问题
热点问题
1原因分析(1/4):
热点问题
由于查询模式或底层Tibs机制的限制,一小部分数据要比其他部分承担更多的负载。
当热点数据不能均匀分布在不同的TIKV实例之间时,一个小的实例集或单个实例将成为整个集群的性能瓶颈热点引起的性能问题
不能通过添加Tikv实例来缓解。
2原因分析(2/4):
顺序写
写入模式是顺序的
一直添加记录
索引值不断地增加/减少
涉及auto_increment
插入数据到新创建的表
一个空表只有一个region,写一段时间后才会分裂和调度
3原因分析(3/4):
热点小表
非常小的数据量(在单一region内)
高并发查询
通常读请求,如范围扫描
可能涉及复杂的表达式
特别注意观察coprocessor metrics
写入:小范围内的大量更新操作
原因分析(4/4):
region分布偏斜
中等大小的数据(大约几十到几百个regions)
区域集中在部分TiKV实例上
读写热点都是可能的
频繁范围扫描
高并发随机插入/更新
预防热点问题方法
表分区
需要使用 hash partition(原理 底层分布层面步同partition 就是不同表)
分区适用于写热点
将顺序插入更改为离散插入
初始状态下的单点写变为多点写
使用 SHARD_ROW_ID_BITS 处理热点表(row_id增长将随机 而不是递增)
通过设置 SHARD_ROW_ID_BITS,可以把 RowID 打散写入多个不同的 Region,缓解写入热点问题
建表时设置 SHARD_ROW_ID_BITS
Create table t(c int) SHARD_ROW_ID_BITS=4
建表后配置
Alter table t SHARD_ROW_ID_BITS=4
Pre-split Region
在插入任何数据之前分割区域
区域会提前分散到所有TiKV实例中
使用边界值分割
使用分割点进行分割
部分分割语法如下
SPLIT TABLE table_name [INDEX index_name] BETWEEN (lower_value) AND (upper_value) REGIONS region_num
SPLIT TABLE t BETWEEN (-9223372036854775808) AND (9223372036854775807) REGIONS 16;
SPLIT TABLE t BY (10000), (90000);
参考文档https://docs.pingcap.com/zh/tidb/stable/sql-statement-split-region
处理热点问题
处理热点(1/3):
Follower Read
允许 读取region Follower replicas
适用于:
read热点
非常小的数据量(在一个区域内)
用法:设置会话变量tidb_replica_ read
1.Read from only follower
Set @@tidb_replica_read=’follower’;
2.read from follower or leader
Set @@tidb_replica_read=’leader-and-follower’
Scatter Range 处理region分布偏斜的问题
Strat scatter range
Curl -X POST http://{tidb_host}:10080/TABLES/{db}/{tables}/scatter
Stop scatter range
Curl -X POST http://{tidb_host}:10080/TABLES/{db}/{tables}/stop-scatter
非常规手段选择Shuffle leader/region
随机移动所有区域的leader或副本
适合读热点(shufflleader)或写热点(shuffregion)
创建scheduler(使用pd-ctl)
Pd-ctl scheduler add shuffle-region-scheduler
Pd-ctl scheduler add shuffle-leader-scheduler
Remove scheduler(使用 pd-ctl)
Pd-ctl scheduler remove shuffle-region-scheduler
Pd-ctl scheduler remove shuffle-leader-scheduler
性能调优 - 故障排查实战
Cpu瓶颈
CPU band
CPU usage过高
application peer:当CPU占用率超过80%时,需要添加更多的应用实例
TiDB server peer:如果CPU占用率超过80%,需要添加更多的TiDB -server实例
TiKV组件:每个组件有足够的线程吗?
gRPC,unfiled thread pool,raftstore pool,apply pool(我们可以从grafana TikV-details页面线程CPU面板看到每个组件的CPU使用情况)
CPU load负载过高
Application peer:是否有太多的进程/线程?上层切换太多?
TikV peer: iowait高吗?如果是,则说明磁盘负载过高。
IO
IOPS限制
ITB EBS gp2卷的限制为3000IOPS
读请求可能会消耗很多IOPS,块缓存大小是否足够大?
IO带宽限制
一个EBS gp2卷有250MB/s IO带宽限制
TiKV压缩流将读取SST文件和写入SST文件,这将消耗大量的IO带宽。我们可以为压缩设置一个速率限制:[rocksdb] rate-bytes-per-sec = “100MB”
范围扫描请求也可能会占用大量I0带宽,比如“select * where range between x and y”。
Network band
应用服务器和TiDB服务器之间的网络
TikV服务器和TiDB服务器之间的网络
例子
Tidb numa问题
现象
TIDB CPU usage不高,但是“PD TSO Wait duration”和“SQL Compile duration”比较高,达到100ms
分析
CPU使用率不高,但“SQL Compile duration”和“PD TSO Wait duration”是高在同一时间,我们怀疑有问题在运行时。
让我们使用“go trace”来诊断它
curl http://127.0.0.1:10080/debua/pprof/trace?seconds= 20 >trace.out
go工具trace trace.out
我们可以看到GC任务持续了50ms-60ms,这是不正常的,我们猜测访问内存的延迟是慢的
根本原因
用户告诉我们TiDB部署在一个 16c VM上,这些16c cross 2 NUMA节点。
虚拟机调整为一个NUMA节点绑定16个核后,持续时间会减少很多
现象
查询延迟随着QPS的增加而增加(来自Grafana TiDB摘要面板)
TiKV CPU使用和IO使用远离瓶颈(来自Grafana TiKV-details服务器面板),TiKV rpc is fast (TiKV-details gRPC面板)
PD说它的延迟很低(从Grafana Pd 页面 Tidb 面板), 但TiDB说“PD TSO等待时间”很高
网络时延低
分析
延迟随着QPS的增加而增加,这意味着一些组件可能会遇到瓶颈
TiKV CPU和IO的使用都远离瓶颈,TiKV说它的RPC速度很快,所以瓶颈不在TiKV这边。
PD表示其延迟较低,但TiDB表示“PD TSO等待时间”较高,瓶颈可能在TiDB侧,或网络延迟较高
但是由于网络延迟较低,瓶颈可能在TiDB端
TiDB所在实例的CPU占用率约为20%+,还远远不够瓶颈
根本原因
TiDB在配置文件[performance]中设置CPU限制max-procs = 8(这个参数一般设置为0)
此配置将限制TiDB进程的CPu占用率为8核
在将max-procs设置为0(unlimited)之后,这个问题就解决了
现象
Tikv 的cpu usage 达到瓶颈
分析
大部分CPU被Coprocessor吃掉(来自Grafana TikV-details页面线程- CPU面板)
我们在TiDB慢速日志中得到一些慢速查询
在explaining了一些很慢的查询之后,我们发现有些查询会导致表扫描(表扫描是昂贵的执行程序,会消耗很多CPU/IO)。
根本原因
查询条件列没有索引添加相关索引后,CPU占用率大大降低
现象
写延迟非常高
TiDB/TiKV/PD CPU占用率过低
分析
gRPC延迟高(来自Grafana TikV-details页面gPRC panel),所以瓶颈在TikV方面TiKV
CPU占用率不高,瓶颈不是CPU
写时间和读(查找/获取)时间非常长,达到几秒。
我们还可以看到有“写暂停”事件,这是磁盘可能超载的重要信号
根本原因
磁盘超负荷,添加更多的TikV节点或控制应用程序的写入流