【TiDB 使用环境】生产环境
【TiDB 版本】v6.5.3
【问题现象】
自增主键写入密集时,单个 TiKV CPU/写入明显高于其他节点。已尝试对部分新表加 SHARD_ROW_ID_BITS,老表上千张不好逐个改。
想请教:
1)对存量表用 SPLIT / PD 调度能缓解到什么程度?
2)是否建议逐步迁到 AUTO_RANDOM 或业务侧打散键?
3)如何快速确认当前热点是 Region 还是索引热点?
有 Dashboard / PD 排查路径更好。
非聚簇表,SHARD_ROW_ID_BITS 只对新写入的数据有效;
自增主键一般都是cluster表,建议修改为auto_random;
看热力图能直接区分是是否是索引热点或者查询tidb_hot…表。
- 先通过 Dashboard 定位前 N 张热点表,优先处理高写入热点表,避开业务高峰执行 DDL
- 对有连续 ID 范围查询的核心表:优先业务前缀复合主键方案,不要直接改成纯 AUTO_RANDOM
- 纯 SPLIT/PD 调度只做短期过渡
存量表用 SPLIT TABLE 预切 Region 配合 PD scatter 打散,Dashboard 热点可视化定位到 key 范围。对自增主键老表迁 AUTO_RANDOM 是长期方案。区分索引热点看 Coprocessor CPU vs Store CPU,sidl/flow 指标偏前段则是索引。
一.SPLIT 的本质:它只是在 _tidb_rowid 的空间上预先画了几个切分点(split points),把 [0, 2^63) 这个区间物理切割成多个 Region。但关键问题在这里:如果写的是单调递增的自增主键(CLUSTERED 表),新写入的 RowID 一个比一个大——它们永远落在最末尾那个Region 的范围内。SPLIT 切分出的前面那些 Region 根本不会收到任何新写入。
二.PD 热调度做了什么
- 探测热点:通过 TiKV 心跳中的 StoreState(磁盘、读写速率)和 RegionState(Leader 位置、读写速率)检测
- 热 Region 识别:检查 min-hot-byte-rate(默认 100)、min-hot-key-rate(默认 10)、min-hot-query-rate(默认 10),超过任一阈值即标记为 hot
- 生成调度 Operator:TransferLeader(迁 Leader)、AddReplica/RemoveReplica(迁副本)
- 间隔控制:minHotScheduleInterval(1秒)、maxHotScheduleInterval(20秒)
PD 能做的是:把热 Region 的 Leader 从高负载 TiKV 迁移到低负载 TiKV。但它不会改变"写入集中在最后一个 Region"这个事实——热Region 只是从一台机器挪到了另一台。
三.AUTO_RANDOM 用于解决自增主键写入热点问题,建议配合 PRE_SPLIT_REGIONS 在建表时预切分 2^(PRE_SPLIT_REGIONS) 个 Region。
总之,
自增主键 CLUSTERED 表:
INSERT →Row Key 单调递增 →始终落在末尾 Region
→该 Region Leader 所在 TiKV CPU/写入 远高于其他节点
SPLIT/PD 调度
preSplitPhysicalTableByShardRowID() →切 Key Range
balance-hot-region-scheduler →迁 Leader
但单调递增 Key 恒落末尾 Region,不受切分影响
AUTO_RANDOM
GetCurrentShard() →MurmurHash3(StartTS) →shard bits
不同事务得到不同 shard →写入散列到不同 Region
SHARD_ROW_ID_BITS 有限制
仅对 NONCLUSTERED 表有效
CLUSTERED 表(TiDB 5.0+ 默认)设置无效
建议先通过 Dashboard → Key Visualizer 确认热点类型:看流量图是单点峰值还是多行密集写入,前者是 Region 热点,后者是索引热点。
- 存量表用 SPLIT TABLE 加 SCATTER 能临时缓解,但自增主键写入会持续往新 Region 倾斜,治标不治本。PD 调度对写入热点效果有限。
- 强烈建议逐步迁移到 AUTO_RANDOM 或业务侧打散键(如用哈希前缀)。这是最彻底的方案,尤其对上千张表,可以写脚本批量改表结构。
AUTO_RANDOM可以解决
– 查看索引的Region分布
SHOW TABLE T1 INDEX idx_name REGIONS;
– 查看每个 Region 的详细信息
SELECT
r.REGION_ID,
r.START_KEY,
r.END_KEY,
r.WRITTEN_BYTES,
r.READ_BYTES,
r.APPROXIMATE_SIZE,
r.APPROXIMATE_KEYS,
p.STORE_ID,
p.IS_LEADER
FROM INFORMATION_SCHEMA.TIKV_REGION_STATUS r
LEFT JOIN INFORMATION_SCHEMA.TIKV_REGION_PEERS p ON r.REGION_ID = p.REGION_ID
WHERE r.TABLE_ID = 23477
AND r.IS_INDEX = 0
ORDER BY r.START_KEY, p.IS_LEADER DESC;
– 可以看到:region id;leader store;region size
– 用于:数据热点分析;region不均衡分析
SELECT *
FROM information_schema.tikv_region_status
WHERE db_name=‘db_name’
AND table_name=‘table_name’;
建议通过查询找出写入量最大、表数据量最大 的 Top 10~20 核心业务表,优先将这些表改造为 AUTO_RANDOM 。
治本的手段:
还是得问问研发,这么热点的写入是否必须的?必须写的话,是否一定要写入数据库里,能否先写MQ,后面再慢慢消费?一定要写到数据库里,那写入的字段能不能尽量精简?
另外,有上千张老表,得定位下是那几张表导致的Tikv CPU打满,这样改造的范围就是几张表不是全部的上千张。