TiDB热点问题

为什么TiDB会有热点问题?

  1. 数据分布不均匀:
    TiDB 将数据分散存储在多个 TiKV 节点上,数据通过 Region 来组织,每个 Region 是一段连续的 Key 范围。如果数据的写入或访问模式导致某些 Region 的负载远高于其他 Region,就会出现热点。
  2. 表设计和主键选择:
    如果表的主键是单调递增的(如自增 ID),那么新插入的数据都会集中在一个 Region 上,这会导致写入热点。类似地,如果查询模式总是围绕某个特定的键值集中,那么这部分数据所在的 Region 也会成为读取热点。
  3. 调度和负载均衡策略:
    TiDB 依赖调度算法来实现数据的负载均衡。如果调度策略不够灵活或响应不够及时,可能无法迅速缓解热点问题。
  4. TiKV 节点性能差异:
    如果集群中的 TiKV 节点性能参差不齐,那么性能较低的节点可能会成为热点,因为它们处理请求的速度跟不上其他节点。
  5. 事务和访问模式:
    某些特定的事务或访问模式可能会频繁访问同一组数据,尤其是在业务高峰期间,这也可能导致热点。

1 AUTO_INCREMENT的热点

TiDB的数据是按照有序的range进行划分的,主键自增,会导致写入都发生在做最后的range上,因此最后的range会是热点。

从 TiDB 编码规则可知,同一个表的数据会在以表 ID 开头为前缀的一个 range 中,数据的顺序按照 RowID 的值顺序排列。在表 insert 的过程中如果 RowID 的值是递增的,则插入的行只能在末端追加。当 Region 达到一定的大小之后会进行分裂,分裂之后还是只能在 range 范围的末端追加,永远只能在一个 Region 上进行 insert 操作,形成热点。
常见的 increment 类型自增主键就是顺序递增的,默认情况下,在主键为整数型时,会用主键值当做 RowID ,此时 RowID 为顺序递增,在大量 insert 时形成表的写入热点。
同时,TiDB 中 RowID 默认也按照自增的方式顺序递增,主键不为整数类型时,同样会遇到写入热点的问题。

解决AUTO_INCREMENT的热点
使用AUTO_RANDOM来生成主键,将主键做了随机化。
弊端:失去了宏观上的有序性。

2 DATETIME的热点

TiDB中索引的编码方式:

Key: tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue_rowID

在比较大小的时候从前往后比较,如果前面可以比较出大小就不往后比较。
有序的indexID DATETIME类型数据,让前段indexId值都不同,导致索引值和DATETIME分布完全相同,数据分布就没有随机性了。

DATETIME类型,包含了日期与时分秒(微秒)信息。按时间不停写入的数据,不停的在增长的有序数据,与AUTO_INCREMENT的主键类似,它也会不停的往最后一个range进行写入,因此最后一个range会成为热点。

解决DATETIME的热点

  1. 使用DATE类型,并且主键使用AUTO_RANDOM。缺点是无法存储时分秒,主键也失去了宏观上的自增性;
  2. 使用DATE类型,并且和另一个不自增的离散列创建组合索引。例如idx_gmt_create;
  3. 使用DATE类型,并且主键使用SHARD_ROW_ID_BITS。缺点是无法存储时分秒,主键失去了宏观上的自增性,并且SHARD_ROW_ID_BITS与主键使用聚簇相冲突,这会造成写入的放大以及主键查询需要做回表;
  4. 注意DATE类型即使在平时没有热点,在0点时刻也可能带来剧烈抖动
  5. 使用分区表,这样时间索引成为了分区内的Local索引,等于按分区做了打散。这是目前能想到的DATETIME类型上使用索引又避免热点的唯一方法,但代价也很大,TiDB目前不支持在分区表上创建全局索引,不带分区键的查询性能上也容易有问题,这对业务代码有很强的侵入性。

如何解决热点问题?

  1. 调整表结构和索引:优化数据模型,避免使用自增主键,因为这会导致写入操作集中在表的末尾。可以使用哈希、UUID 或者其他策略来分散写入。
  2. 分裂热点 Region:手动或自动分裂负载较高的 Region,使得热点数据分散到多个 Region 和多个 TiKV 节点上。
  3. 调整调度策略:通过调整 TiDB 的调度策略,使得热点数据能够更均匀地分布在多个 TiKV 节点上。
  4. 扩容集群:增加 TiKV 节点数量,提高集群的处理能力和存储容量。
  5. 使用 TiFlash:对于读取热点,可以使用 TiFlash 列存引擎来分担读取压力,TiFlash 能够加速分析型查询。
  6. 流量控制:对于高并发的写入或读取操作,可以通过限流等方式来控制单个节点的压力。
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值