目录
一、热点问题简介
TiDB 作为分布式数据库,内建负载均衡机制,尽可能将业务负载均匀地分布到不同计算或存储节点上,更好地利用上整体系统资源。然而,机制不是万能的,在一些场景下仍会有部分业务负载不能被很好地分散,影响性能,形成单点的过高负载,也称为热点。
TiDB 提供了完整的方案用于排查、解决或规避这类热点。通过均衡负载热点,可以提升整体性能,包括提高 QPS 和降低延迟等。
在 MySQL 中都会指定自增主键,从 MySQL 迁移到TIDB上时,可能会习惯性的创建自增主键 ID,TiDB 官方文档已经明确说明使用自增主键时 TiDB 会有热点问题,写入的数据都是连续的,那么就会插入到少数几个 Region 中,造成写入热点,那自增 ID 的情况下如何将数据打散呢?这篇文章带你深入解读。
二、热点场景
TiDB 是通过 KV 类型的结构来保存数据,关于 TiDB 是如何通过键值对来保存数据的问题,请参考往期文章:TiDB内核解密:揭秘其底层KV存储引擎如何玩转键值对-优快云博客 ,这里就不详细介绍了。
TiDB 对每个表分配一个 TableID,每一个索引都会分配一个 IndexID,每一行分配一个 RowID(默认情况下,如果表使用整数型的 Primary Key,那么会用 Primary Key 的值当做 RowID)。其中 TableID 在整个集群内唯一,IndexID/RowID 在表内唯一,这些 ID 都是 int64 类型。
2.1 表热点
同一个表的数据会在以表 ID 开头为前缀的一个 range 中,数据的顺序按照 RowID 的值顺序排列。在表 insert 的过程中如果 RowID 的值是递增的,则插入的行只能在末端追加。当 Region 达到一定的大小之后会进行分裂,分裂之后还是只能在 range 范围的末端追加,永远只能在一个 Region 上进行 insert 操作,形成热点。
常见的 increment 类型自增主键就是顺序递增的,默认情况下,在主键为整数型时,会用主键值当做 RowID,此时 RowID 为顺序递增,在大量 insert 时形成表的写入热点。
同时,TiDB 中 RowID 默认也按照自增的方式顺序递增,主键不为整