小表读热点及如何region切分问题

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
4.0.11

【概述】 场景 + 问题概述
目前有几个小表 几十万条数据,但是热点很高 想尝试做region切分,看了下官方文档 有些疑问

【背景】 做过哪些操作
11月16号 上线新业务高并发全表扫描读小表的语句
【现象】 业务和数据库现象
小表有读热点


【问题】 当前遇到的问题
问题1:想排查频繁出现TiDB tikvclient_backoff_count error 以及TiKV coprocessor request error告警的原因
初步定位怀疑是 高并发读小表导致region leader一直在切换 出现not leader 请大佬们帮忙看下是不是这个原因 能调整什么参数优化吗

问题2:
尝试合并region没解决问题,想试试region切分 分散小表r热点

查看官方文档

这个BETWEEN (lower_value) AND (upper_value). 这两个区间值应该如何确认呢看了下文档不懂这个是怎么计算的

我的表 region信息是这样的
mysql> show table temporary_freeze regions;
±----------±----------±--------±----------±----------------±-----------------±-----------±--------------±-----------±---------------------±-----------------+
| REGION_ID | START_KEY | END_KEY | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
±----------±----------±--------±----------±----------------±-----------------±-----------±--------------±-----------±---------------------±-----------------+
| 3408 | t_332_ | t_334_ | 3409 | 1 | 3409, 3410, 3411 | 0 | 0 | 0 | 4 | 36172 |
±----------±----------±--------±----------±----------------±-----------------±-----------±--------------±-----------±---------------------±-----------------+


1 row in set (0.00 sec)

想请问大佬们我应该如何均匀切分
BETWEEN (lower_value) AND (upper_value)这两个值改取什么区间

【业务影响】

【TiDB 版本】

【应用软件及版本】

【附件】 相关日志及配置信息

  • TiUP Cluster Display 信息
  • TiUP CLuster Edit config 信息

监控(https://metricstool.pingcap.com/)

  • TiDB-Overview Grafana监控
  • TiDB Grafana 监控
  • TiKV Grafana 监控
    查看TIKV cpu有明显的热点现象

16号新业务上线高并发扫描几个小表 发现在空region一直有波动 尝试merge了region 把空region合并降低


KV Backoff 有出现regionMiss 和staleCommand现象

以及出现了很多not_leader的告警 怀疑是不是因为热点问题导致leader一直在2个kv节点飘来飘去

  • PD Grafana 监控
  • 对应模块日志(包含问题前后 1 小时日志)
    tidb日志
    [2021/12/02 16:23:52.622 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3432] [currIdx=0] [leaderStoreID=5]
    [2021/12/02 16:23:54.538 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3232] [currIdx=0] [leaderStoreID=4]
    [2021/12/02 16:23:55.828 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3400] [currIdx=0] [leaderStoreID=4]
    [2021/12/02 16:23:56.817 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3396] [currIdx=0] [leaderStoreID=5]
    [2021/12/02 16:23:58.142 +08:00] [INFO] [coprocessor.go:1034] [“[TIME_COP_PROCESS] resp_time:325.030949ms txnStartTS:429505495121526785 region_id:92 store_addr:172.25.2.164:20160”] [conn=5496678]
    [2021/12/02 16:23:58.822 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3404] [currIdx=0] [leaderStoreID=5]
    [2021/12/02 16:24:02.417 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3392] [currIdx=0] [leaderStoreID=5]
    [2021/12/02 16:24:07.430 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=92] [currIdx=0] [leaderStoreID=5]
    [2021/12/02 16:24:12.999 +08:00] [INFO] [coprocessor.go:1034] [“[TIME_COP_PROCESS] resp_time:438.811324ms txnStartTS:429505498975043597 region_id:104 store_addr:172.25.2.165:20160 kv_process_ms:229 scan_total_write:100923 scan_processed_write:100922 scan_total_data:0 scan_processed_data:0 scan_total_lock:1 scan_processed_lock:0”] [conn=6321738]
    [2021/12/02 16:24:29.167 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=3376] [currIdx=2] [leaderStoreID=4]
    [2021/12/02 16:24:38.866 +08:00] [INFO] [region_cache.go:840] [“switch region leader to specific leader due to kv return NotLeader”] [regionID=100] [currIdx=1] [leaderStoreID=1]

上传了其中一天的tikv日志
tikv.log.2021-11-19-19:10:28.754589497 (32.4 MB)

[2021/12/01 21:52:20.601 +08:00] [INFO] [process.rs:136] [“get snapshot failed”] [err=“Request(message: "peer is not leader for region 3380, leader may Some(id: 3383 store_id:
5)" not_leader { region_id: 3380 leader { id: 3383 store_id: 5 } })”] [cid=146419]
[2021/12/01 21:52:20.601 +08:00] [INFO] [process.rs:136] [“get snapshot failed”] [err=“Request(message: "peer is not leader for region 2840, leader may Some(id: 2843 store_id:
5)" not_leader { region_id: 2840 leader { id: 2843 store_id: 5 } })”] [cid=146420]

[2021/12/01 21:52:25.128 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 7480000000000000315F69800000000000000101323032313131
3136FF3232333130656237FF3034303135633932FF3234643933316632FF3030303230323930FF3461623700000000FB lock_version: 429488012004163987 key: 74800000000000014C5F728001400000744A0C loc
k_ttl: 20073 txn_size: 1 lock_for_update_ts: 429488012017270878”]
[2021/12/01 21:52:25.133 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 7480000000000000315F69800000000000000101323032313131
3136FF3232333130656237FF3034303135633932FF3234643933316632FF3030303230323930FF3461623700000000FB lock_version: 429488012004163987 key: 74800000000000014C5F728001400000744A0C loc
k_ttl: 20073 txn_size: 1 lock_for_update_ts: 429488012017270878”]

通过region key 命令找到 region

tiup ctl pd -u http://{pdip:port} -i

region key 7480000000000000315F698000000000000001013230323131313136FF3232333130656237FF3034303135633932FF3234643933316632FF3030303230323930FF3461623700000000FB
{
“id”: 6,
“start_key”: “”,
“end_key”: “7480000000000000FF0500000000000000F8”,
“epoch”: {
“conf_ver”: 5,
“version”: 2
},
“peers”: [
{
“id”: 7,
“store_id”: 1
},
{
“id”: 46,
“store_id”: 4
},
{
“id”: 67,
“store_id”: 5
}
],
“leader”: {
“id”: 7,
“store_id”: 1
},
“written_bytes”: 0,
“read_bytes”: 476,
“written_keys”: 0,
“read_keys”: 7,
“approximate_size”: 1,
“approximate_keys”: 1
}

查看一下 region 元数据信息,显示这是个空region

SELECT * FROM INFORMATION_SCHEMA.TIKV_REGION_STATUS WHERE region_id=6;

尝试进行合并region后
再次查询id 变成 了24 已经不是空region了

查看tikv日志报错还是挺多的
[2021/12/01 20:58:09.448 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 74800000000000014C5F72800140000074492A lock_version: 429487158555051004 key: 74800000000000014C5F72800140000074492A lock_ttl: 3001 txn_size: 1”]
[2021/12/01 20:58:09.451 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 74800000000000014C5F72800140000074492A lock_version: 429487158555051004 key: 74800000000000014C5F72800140000074492A lock_ttl: 3001 txn_size: 1”]
[2021/12/01 20:58:09.460 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 74800000000000014C5F72800140000074492A lock_version: 429487158555051004 key: 74800000000000014C5F72800140000074492A lock_ttl: 3001 txn_size: 1”]
[2021/12/01 20:58:09.463 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 74800000000000014C5F72800140000074492A lock_version: 429487158555051004 key: 74800000000000014C5F72800140000074492A lock_ttl: 3001 txn_size: 1”]
[2021/12/01 20:58:09.468 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 74800000000000014C5F72800140000074492A lock_version: 429487158555051004 key: 74800000000000014C5F72800140000074492A lock_ttl: 3001 txn_size: 1”]
[2021/12/01 20:58:13.961 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Region error (will back off and retry) message: "peer is not leader for region 3380, leader may Some(id: 3382 store_id: 4)" not_leader { region_id: 3380 leader { id: 3382 store_id: 4 } }”]
[2021/12/01 20:58:13.961 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Region error (will back off and retry) message: "peer is not leader for region 3380, leader may Some(id: 3382 store_id: 4)" not_leader { region_id: 3380 leader { id: 3382 store_id: 4 } }”]
[2021/12/01 20:58:13.967 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Region error (will back off and retry) message: "peer is not leader for region 3380, leader may Some(id: 3382 store_id: 4)" not_leader { region_id: 3380 leader { id: 3382 store_id: 4 } }”]
[2021/12/01 20:58:13.968 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Region error (will back off and retry) message: "peer is not leader for region 3380, leader may Some(id: 3382 store_id: 4)" not_leader { region_id: 3380 leader { id: 3382 store_id: 4 } }”]


若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

1 个赞

要不先试试Load Base Split:
https://docs.pingcap.com/zh/tidb/dev/configure-load-base-split

1 个赞

我认为这个范围要根据表的数据量来估算,比如这个字段是自增主键,在表里面是1到100万,那就可以按这个范围来打散

1 个赞

有可能现在手动split的后还是会有热点,根据目前的表结构和业务特点重新设计表结构效果更好些,可以使用auto_random 、pre_split_region+shard_rowid_bits或者hash分区

1 个赞

您好 我发现了一种切分方式
tiup ctl pd -u http://pd_ip:2379 -i

operator add split-region 1 --policy=approximate //Region 1 对半拆分成两个 Region ,基于粗略估计值

operator add split-region 1 --policy=scan //Region 1 对半拆分成两个 Region ,基于精确扫描值
用这种方式可以针对热点的region进行对半切分 就是比较不方便 得对半切好几次

不过 看您发的链接说均匀拆分 Region 并不一定是最好的选择,请求可能集中在某几个 Key 上,即使均匀拆分后热点可能仍然集中在其中一个 Region 上,可能需要经过多次均匀拆分才能达到目标。我准备在测试环境尝试下您发的链接方案


看测试环境leader之前一直集中在某一个节点,并不均衡 不知道有没有均衡leader的方式 生产环境的leader一直在波动 不知道是不是热点原因 测试环境很少出现leader波动 基本没有not leader的告警

是的,手动拆分一来是region多了操作不方便,二来也可能会在后面被自动合并,小表高频热点问题基于region的负载自动去拆分可能更好一点

您好 这种方式我知道的 只是这个几个小表涉及面比较大 很多业务去调用 不能轻易去修改 因为使用auto_random 、pre_split_region+shard_rowid_bits 只能解决后续写入的读写热点问题 原先写入的数据还是在一个热点region上 所有要缓解线上热点还是考虑先切分region的方案 等后面研发有新版本发布后再新建表 进行预切分region 重新灌入数据 目前我在测试环境把region切成了4个 读热点分流了。
就是官网的这种切分方式不太理解他的两个边界是怎么定义的image
目前线上一直有这两个告警
image
测试环境也有读热点region却没有出现 所以也不知道是不是热点问题还是region哪里有问题 或者是因为并发读太高导致Key is locked? 之前有一些空region 以及表region有报
[2021/12/01 21:52:20.601 +08:00] [INFO] [process.rs:136] [“get snapshot failed”] [err=“Request(message: “peer is not leader for region 3380, leader may Some(id: 3383 store_id:
5)” not_leader { region_id: 3380 leader { id: 3383 store_id: 5 } })”] [cid=146419]
[2021/12/01 21:52:20.601 +08:00] [INFO] [process.rs:136] [“get snapshot failed”] [err=“Request(message: “peer is not leader for region 2840, leader may Some(id: 2843 store_id:
5)” not_leader { region_id: 2840 leader { id: 2843 store_id: 5 } })”] [cid=146420]

[2021/12/01 21:52:25.128 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 7480000000000000315F69800000000000000101323032313131
3136FF3232333130656237FF3034303135633932FF3234643933316632FF3030303230323930FF3461623700000000FB lock_version: 429488012004163987 key: 74800000000000014C5F728001400000744A0C loc
k_ttl: 20073 txn_size: 1 lock_for_update_ts: 429488012017270878”]
[2021/12/01 21:52:25.133 +08:00] [WARN] [endpoint.rs:537] [error-response] [err=“Key is locked (will clean up) primary_lock: 7480000000000000315F69800000000000000101323032313131
3136FF3232333130656237FF3034303135633932FF3234643933316632FF3030303230323930FF3461623700000000FB lock_version: 429488012004163987 key: 74800000000000014C5F728001400000744A0C loc
k_ttl: 20073 txn_size: 1 lock_for_update_ts: 429488012017270878”]
尝试合并rengion 后消除了一些空region 告警还是挺多的没啥变化

边界是rowid,范围 minInt64 到 maxInt64 (-9223372036854775808) AND (9223372036854775807)

split.byte-threshold (流量阈值) 这个参数似乎没有

可以先设置看看

如果小表的数目大于tikv的数目,就不用切,每个tikv上一个热点region就可以。
用下面的命令查每个表的region,可以把几个表的region都查出来,看下regionid是不是一样,如果几张小表都放在了同一个region上,可以设置

tidb-ctl  --host xxx table regions -d <dbname> -t  <tablename>    

把某个region的leader迁移到其他tikv上。

pd-ctl  operator add transfer-region <regionid>   <storeid> leader 

其中,每个表的region分为数据region和索引region,索引region也需要均衡。

然后相应的再调优下tikv线程数,基本上能解决问题。
https://docs.pingcap.com/zh/tidb/v4.0/tune-tikv-thread-performance

我把qps那个参数调低了 确实能切分 会短暂影响查询 这个方法确实不错 方便多了 就是不敢一下子调整太低 哈哈 不然会短时间一直在切 对查询会有些影响

:+1: region频繁被切分调度肯定是对性能有影响的,所以参数值要实际情况去取舍

好的 感谢您 我研究下这个leader迁移 和线程调优 目前生产有个怪现象就是 leader一直在几个kv节点切来切去的 日志一直有很多not leader告警 测试环境却不会 不知道是否有哪个参数会影响leader的自动切换

pd-ctl scheduler show
看看有没有shuffer-region或shuffer-leader
pd-ctl config show
看看leader-schedule-limit是多少,可以通过这个限制调度速度
但是根本的还是找到为什么会迁移,比如说tikv压力大之类的。

https://docs.pingcap.com/zh/tidb/stable/configure-load-base-split#load-base-split
你们是说的Load Base Split这个方法么?

是的 这种方法自动切分qps大的热点region 不过这种方法比较不可控 调整太低容易一下子切分很多个region出来

我理解,如果低于设定值,是不是就不会分裂,这样其实就把小表的读热点控制在一个确定的流量控制之下?

是的 应该还有另一个参数 是按扫描字节量控制切分 那个也会影响