作者:翟玉龙,施闻轩

本文适用于 TiDB 4.0 版本,介绍了如何定位和解决写入热点问题。关于读热点的处理方法,可临时参考下面的帖子,也请期待我们的后续补充

TiDB 作为分布式数据库,自身拥有一些负载均衡机制,尽可能将业务负载均匀地分布到不同计算或存储节点上,更好地利用上整体系统资源。然而,机制不是万能的,在一些场景下仍会有部分业务负载不能被很好地分散,影响性能,形成单点的过高负载,也称为热点。

TiDB 提供了完整的方案用于排查、解决或规避这类热点。通过均衡负载热点,可以提升整体性能,包括提高 QPS 和降低延迟等。

需要说明的是,性能问题不一定是热点造成的,也有可能有多个因素共同影响,在排查前需要先确认是否与热点相关(见下文)。另外,即使业务负载严重不均衡、热点明显,也不会引发正确性问题。



确认存在写热点

判断依据:打开监控面板 TiKV-Trouble-Shooting 中 Hot Write 面板(如下图所示),观察 Raftstore CPU 监控是否存在个别 TiKV 节点的指标明显高于其他节点的现象。



示例:存在写热点

18:30 前有单个 TiKV 实例的 Raft store CPU 比其他节点高出将近一倍,存在写入热点。在 18:30 后,写入热点得到了缓解。

如何分析和解决 TiDB 4.0 的写热点问题_主键



示例:负载均衡、不存在明显热点

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_02



示例:负载不够均衡,但不是热点

需要注意排除以下案例,监控中负载有一定的不均衡,但因为并非个别 TiKV CPU 指标过高,因此不构成热点:

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_03



使用 TiDB Dashboard 定位热点表

TiDB Dashboard 中的「热点可视化」功能可帮助用户缩小热点排查范围到表级别。以下是一个「热点可视化」功能展示的热力图样例,该图横坐标是时间,纵坐标排列了各个表和索引,颜色越亮代表其流量越大。可在工具栏中切换显示读或写流量。

如何分析和解决 TiDB 4.0 的写热点问题_自增_04

当图中写入流量图出现以下明亮斜线(斜向上或斜向下)时,说明该大流量表构成了写入热点:

如何分析和解决 TiDB 4.0 的写热点问题_自增_05

将鼠标移到亮色块上,即可看到是什么表或索引具有大流量,如下所示:

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_06

大多数情况下,显著的热点都会来自于表数据。索引热点有存在的可能性,但一般不大显著,因此本文不覆盖。

这类写入热点主要有以下几种成因:

成因

规避或解决方案

自增主键

不要使用自增主键,可改用 UUID 等,或使用 AUTO_RANDOM

无主键/联合主键/非 INT 类型主键

使用 SHARD_ROW_ID_BITS

INT 类型主键,且连续写入数值接近的主键

将该主键改为普通索引,再使用 SHARD_ROW_ID_BITS

写入流量图中以下这类亮色横线对应的则是另一种热点模式:热点小表,但 TiDB 内置机制还不能很好地缓解这个情况,建议通过业务侧增加缓存等方法绕过:

如何分析和解决 TiDB 4.0 的写热点问题_自增_07

可阅读「​​TiDB in Action - 2.1 识别集群热点和业务模式​​」进一步了解「热点可视化」工具的使用。



使用 SHARD_ROW_ID_BITS 处理热点表

本方法不适用于自增主键,自增主键可用下文的 AUTO_RANDOM 方法。另外如果热点表的主键是 INT 类型,使用本方法前需先去除主键改为普通索引。

通过设置表的 ​​SHARD_ROW_ID_BITS​​ 属性可以将相邻的行写入转化为离散的行写入,缓解热点。样例如下:

CREATE TABLE t (a INT) SHARD_ROW_ID_BITS = 4;

ALTER TABLE t SHARD_ROW_ID_BITS = 4;

SHARD_ROW_ID_BITS 的值决定了打散程度,用户可根据 TiKV 个数以及打散效果决定和调整该值的大小:

  • SHARD_ROW_ID_BITS = 4 表示 16 个分片
  • SHARD_ROW_ID_BITS = 6 表示 64 个分片
  • SHARD_ROW_ID_BITS = 0 表示默认值 1 个分片

SHARD_ROW_ID_BITS 的值可以动态修改,每次修改之后,只对新写入的数据生效。

注意:SHARD_ROW_ID_BITS 不宜设置得过大,否则会造成 TiDB 与 TiKV 之间内部请求数放大(与分片数相关),增加 CPU 和网络开销,无法取得最佳性能。

以下是两张无主键情况下使用 SHARD_ROW_ID_BITS 打散热点后的流量图,第一张展示了打散前的情况,第二张展示了打散后的情况。

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_08

如何分析和解决 TiDB 4.0 的写热点问题_自增_09

由流量图可见,设置 SHARD_ROW_ID_BITS 后,流量热点可以由之前的很集中变得很分散。

更详细的使用方法可以阅读 ​​SHARD_ROW_ID_BITS 文档​​。


使用 AUTO_RANDOM 处理自增主键热点表

适用于代替自增主键,解决自增主键带来的写入热点。

该功能目前还是实验性功能,不推荐生产环境使用。可使用以下配置启用:

[experimental]

allow-auto-random = true

使用该功能后,将由 TiDB 生成随机分布且空间耗尽前不重复的主键,达到离散写入、打散写入热点的目的。注意,TiDB 生成的主键不再是自增的主键,可使用 LAST_INSERT_ID() 获取上次分配的主键值。

接下来,将建表语句中的 AUTO_INCREMENT 改为 ​​AUTO_RANDOM​​ 即可使用该功能,示例如下:

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_10

以下是将 AUTO_INCREMENT 表改为 AUTO_RANDOM 打散热点后的流量图,第一张是 AUTO_INCREMENT,第二张是 AUTO_RANDOM。

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_11

如何分析和解决 TiDB 4.0 的写热点问题_负载均衡_12

由流量图可见,使用 AUTO_RANDOM 代替 AUTO_INCREMENT 可以很好地打散热点情况。

更详细的使用方法可以阅读 ​​AUTO_RANDOM 文档​​。


阅读其他相关资料

​TiDB 高并发写入场景最佳实践​

​Split Region 使用文档​