TIDB-热点

时间:2021-09-24 03:45:28   收藏:0   阅读:26

对于分布式数据库来说,热点和事务冲突是两个需要避免的场景,在很多客户测试的案例中,经常出现热点引起的性能未达预期的情况。本文借近期遇到的几个客户场景,对热点问题在 TiDB 中的表现形式和影响,以及如何应对做一个记录。

何为热点

热点可以理解为热点数据,或者说热点 region,TiDB 自带的 grafana 监控指标中也有 hot region write / read 的 metrics。但是我的理解热点问题更准确的表现形式,其实是 某(几)个tikv 节点的 corprocessor / scheduler (负责读/写模块的线程)消耗资源过高,而剩下的 kv 节点资源白白闲置。对于分布式系统来说,优点突出但是可能存在木桶效应,某一个组件/服务器资源瓶颈,会影响到整个集群的表现。

判断热点现象也很简单,查看 tikv 监控页面的 thread CPU 监控项,如果发现 corprocessor 或 scheduler 中各 kv 实例的 CPU 消耗十分不均匀,那大概率就是碰到热点现象了。

产生热点的原因

产生热点现象的原因有多种,大致总结可分为以下:

  1. 部分小表例如配置表的频繁访问引起热点
  2. MySQL 中自增主键的高并发写入
  3. 非自增,但时间相关的顺序插入
  4. 无主键,或主键为非 int 类型
  5. 时间相关字段的索引
  6. 业务逻辑/数据分布产生的热点读写
  7. 执行计划不合理引起的非必要全表/错误的索引扫描

如何规避

热点的解决思路有两种,一是加快单次处理的速度,二是将频繁请求的数据分散到不同的 region,然后通过 pd 调度或手工的方式,将 region 的 leader 调度到多个kv 实例中。

针对上面的情况,逐一分析。

热点 Case 记录

case1:某视频播放平台业务压测写入瓶颈

该客户在 TiDB 上进行用户视频播放记录的业务测试,这是目前线上写入量最大的业务单元,峰值 TPS 接近4W,由于客户还未采用分库分表,单个 MySQL 实例几乎无法满足这么大的写入量,所以目前客户是通过 Hbase 的方式来做。

在测试 TiDB 的过程中,发现在3个 tikv 实例的集群中,写入量只能达到4W,由于咱们是支持写扩展的,加到6个 tikv 实例,写入量还是只有4W。在另外一套12个 kv 节点的集群上进行测试,写入也只有4W,无法提升。虽然满足目前线上峰值的需求,但是写入的水平扩展能力并没有得到验证。

通过观察 grafana 监控,发现负责写入的 scheduler 线程有明显的热点情况。确认客户的表结构,是一个业务无关的自增 ID 作为主键, 通过上面shard 的方式打散表后测试写入,在6个 tikv 实例的时候写入能够达到7W,12个 tikv 实例的时候写入能够稳定在11W+,不仅写入能力大大超出客户预期,水平扩展能力也得到验证。

case2:某电商平台业务压测写入瓶颈

客户在 TiDB 上测试单张业务表(超过20亿数据)的写入性能,由于表结构较为复杂,平均长度达到了2kb,在使用自增 ID 的情况下,写入瓶颈在2.5W TPS。

使用上述方式修改表结构为 shard 模式后,发现仍然存在热点现象,后确认表结构存在两个时间字段的索引,上面提到索引也可能会造成热点。先去掉时间索引进行测试,发现 TPS 还是上不去,热点现象仍然存在。

跟客户确认具体的压测逻辑,业务代码自己维护了一张类似计数器的配置表,多线程并发写入数据的时候,每个线程每次取步长1000,而客户压测共采用了40个客户端模拟,并发量达到了2W,这样热点情况没有出现在业务表,反而出现在了负责计数器功能的配置表上。建议客户调整步长后,经过多次测试,在步长为500W 时,能够有效避免热点效应,TPS 能够达到10W。

这个 case 后面还发生了一些有意思的现象。

调整表结构为 shard,步长为500W后,虽然 TPS 能够达到10W,但是在稳定性测试时,发生过几分钟之后 TPS 会降到3W,热点现象又出现了。

通过分析,每次热点的现象都出现在固定的几个 kv 节点。在高强度的写入过程中region 需要不断的分裂并将 leader 调度到其他节点以平衡各 kv 节点的资源消耗。但是通过分析日志发现,每次调度 leader 的时候都会失败,失败的原因是其它副本的数据写入进度远低于该副本,于是无法调度成功。最后我们发现这几个 kv 节点的 SSD 磁盘写入性能要明显优于其它节点。通过调整集群拓扑,将写入性能差距太大的几台服务器调整为 tidb-server,热点情况消失。研发也提供了两个途径来应对这种场景,一是加快分裂的效率,二是优化切换 leader 时校验数据 gap 的策略。

测完写后,继续压测读请求,很不辛又遇到热点了。压测逻辑是在 ID 最大值和最小值之间随机取数发起读请求,按照常理推断,这种压测方式是不应该产生热点的。通过分析推断,造测试数据的时候可能出现了数据倾斜,通过 select count where id > and id < 的方式很容易得到验证。通过过滤筛选,发现在10亿至20亿之间的数据较多,修改测试代码,随机 ID 选在这个范围之内进行测试,发现热点情况消失,QPS 达到35W。

case3:某券商读业务响应慢

查看 grafana 监控,一共3个 tikv 实例,其中一个 kv 的 corprocessor 消耗 CPU 1000%+,另外两台 CPU 确一直闲置,又是一个明显的热点情况。

通过分析业务 SQL,业务表有一个基于 A+B+C 的联合主键,同时也有一个 A 的单列索引,SQL 中 where 条件是基于 A = ? and B = ? and C = ?,2.0.4版本的优化器可能存在一些缺陷,错误的选择了基于 A 的单列索引。

但是通过分析表发现,A 的数据分布倾斜十分严重,某些条件下需要扫描5W+ 数据,更合理的执行计划应该是选择A、B、C 的联合主键。通过 hint 方式临时规避这个问题,同时在2.0.6版本已经解决这个优化器的 BUG,建议客户升级到最新的稳定版本。

转载自:https://asktug.com/t/topic/358

原文:https://www.cnblogs.com/lovezhr/p/15311861.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!