请问为什么要打散regions,默认会超过96M,会自动分割成新的regions

下面这个示例,在插入数据后已经自动分配了94 96 2这3个regions,请问为什么还需要再打散呢?虽然说是热点问题,这样盲目的打散意义是什么?

示例

创建一个示例表,并在若干 Region 中填充足够的数据量:

CREATE TABLE t1 (
 id INT NOT NULL PRIMARY KEY auto_increment,
 b INT NOT NULL,
 pad1 VARBINARY(1024),
 pad2 VARBINARY(1024),
 pad3 VARBINARY(1024)
);
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM dual;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
INSERT INTO t1 SELECT NULL, FLOOR(RAND()*1000), RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000;
SELECT SLEEP(5);
SHOW TABLE t1 REGIONS;

结果显示示例表被切分成多个 Regions。REGION_IDSTART_KEYEND_KEY 可能不完全匹配:

SHOW TABLE t1 REGIONS;
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| REGION_ID | START_KEY    | END_KEY      | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS | SCHEDULING_CONSTRAINTS | SCHEDULING_STATE |
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
|        94 | t_75_        | t_75_r_31717 |        95 |               1 | 95    |          0 |             0 |          0 |                  112 |           207465 |                        |                  |
|        96 | t_75_r_31717 | t_75_r_63434 |        97 |               1 | 97    |          0 |             0 |          0 |                   97 |                0 |                        |                  |
|         2 | t_75_r_63434 |              |         3 |               1 | 3     |          0 |     269323514 |   66346110 |                  245 |           162020 |                        |                  |
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
3 rows in set (0.00 sec)

解释:

上面 START*KEY 列的值 t_75_r_31717 和 END_KEY 列的值 t_75_r_63434 表示主键在 3171763434 之间的数据存储在该 Region 中。t_75* 是前缀,表示这是表格 (t) 的 Region,75是表格的内部 ID。若START_KEYEND_KEY 的一对键值为空,分别表示负无穷大或正无穷大。

TiDB 会根据需要自动重新平衡 Regions。建议使用 SPLIT TABLE REGION 语句手动进行平衡:

SPLIT TABLE t1 BETWEEN (31717) AND (63434) REGIONS 2;
+--------------------+----------------------+
| TOTAL_SPLIT_REGION | SCATTER_FINISH_RATIO |
+--------------------+----------------------+
|                  1 |                    1 |
+--------------------+----------------------+
1 row in set (42.34 sec)
SHOW TABLE t1 REGIONS;
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| REGION_ID | START_KEY    | END_KEY      | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS | SCHEDULING_CONSTRAINTS | SCHEDULING_STATE |
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
|        94 | t_75_        | t_75_r_31717 |        95 |               1 | 95    |          0 |             0 |          0 |                  112 |           207465 |                        |                  |
|        98 | t_75_r_31717 | t_75_r_47575 |        99 |               1 | 99    |          0 |          1325 |          0 |                   53 |            12052 |                        |                  |
|        96 | t_75_r_47575 | t_75_r_63434 |        97 |               1 | 97    |          0 |          1526 |          0 |                   48 |                0 |                        |                  |
|         2 | t_75_r_63434 |              |         3 |               1 | 3     |          0 |             0 |   55752049 |                   60 |                0 |                        |                  |
+-----------+--------------+--------------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
4 rows in set (0.00 sec)

上面的输出结果显示 Region 96 被切分,并创建一个新的 Region 98。切分操作不会影响表中的其他 Region。输出结果同样证实:

  • TOTAL_SPLIT_REGION 表示新切的 Region 数量。以上示例新切了 1 个 Region。
  • SCATTER_FINISH_RATIO 表示新切的 Region 的打散成功率,1.0 表示都已经打散了。

更详细的示例如下:

show table t regions;
+-----------+--------------+--------------+-----------+-----------------+---------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| REGION_ID | START_KEY    | END_KEY      | LEADER_ID | LEADER_STORE_ID | PEERS         | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS | SCHEDULING_CONSTRAINTS | SCHEDULING_STATE |
+-----------+--------------+--------------+-----------+-----------------+---------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
| 102       | t_43_r       | t_43_r_20000 | 118       | 7               | 105, 118, 119 | 0          | 0             | 0          | 1                    | 0                |                        |                  |
| 106       | t_43_r_20000 | t_43_r_40000 | 120       | 7               | 107, 108, 120 | 0          | 23            | 0          | 1                    | 0                |                        |                  |
| 110       | t_43_r_40000 | t_43_r_60000 | 112       | 9               | 112, 113, 121 | 0          | 0             | 0          | 1                    | 0                |                        |                  |
| 114       | t_43_r_60000 | t_43_r_80000 | 122       | 7               | 115, 122, 123 | 0          | 35            | 0          | 1                    | 0                |                        |                  |
| 3         | t_43_r_80000 |              | 93        | 8               | 5, 73, 93     | 0          | 0             | 0          | 1                    | 0                |                        |                  |
| 98        | t_43_        | t_43_r       | 99        | 1               | 99, 100, 101  | 0          | 0             | 0          | 1                    | 0                |                        |                  |
+-----------+--------------+--------------+-----------+-----------------+---------------+------------+---------------+------------+----------------------+------------------+------------------------+------------------+
6 rows in set

比如,上图是某张表regions分布情况,从这张表能看出来regions分布有问题吗?或者说我们打散以什么为出发点呢?

打散的根本目的就是避免读写热点。插入数据后分裂成3个region。本身就涉及了分裂、transfer_leader等操作,如果在创建表的时候就拆分出3个region,起码就避免了一次分裂操作。高负载的情况下触发大量这些操作都会导致性能抖动。
auto_increment拆分region避免不了写热点,需要改为random。
单纯的看数据应该是看不出来热点问题的,具体看使用的情况判定热点。

为什么会有读写热点?
像上面这张表,它已经自动分了很多个regions, 而且leader_store也分布在几个节点中,还需要打散吗?出于什么原因打散呢?

tidb文档都没有解释清楚热点问题,光是说主键按序列顺序或没有主键的表会按顺序生成regions,导致热点,按顺序生成有问题吗?超过96M,会自动生成下一个region,这两个region都是分布在所有的节点中,这个热点有什么关系?

为了避免热点,尽量负载均衡。因为region都存在tikv上,试想一下,如果你有一个很大的事务,写入一批数据,大小为10G,没有设置单个region 96M的大小及分裂的话,当该事务分配到某一个tikv上,那么短期内该tikv的负载就会非常大,磁盘刷数据就会很慢,同时其他两个tikv节点可能处于空闲状态,无法实现负载均衡。打散region 后,比如该事务有120个region,那么3副本情况下每个tikv上分散40个leader节点,每个tikv服务器的压力就会小很多,效率也会增加

当某个 region 的数据量过大时,为了保证系统的性能和稳定性,通常会自动将其分割成多个较小的 region

虽然自动分了 3 个 Region,但大小不均、集中在单个节点、未均匀分布,手动打散是为了让数据和请求均衡分布到不同节点,彻底消除热点、提升并发性能,不是盲目操作。

大量删除数据后磁盘空间不释放,先检查 GC safepoint 是否正常推进。如果某个 TiKV 节点挂了会导致 safepoint 卡住,把节点恢复或者剔除后应该就好了。

现在region很多,数据分散,但是不代表业务上使用的数据是分散的,有可能某个频繁的查询的数据刚好都落在了少量的几个region中,因此会有热点。这个也是结合业务设计和热点监控来处理的,并不是region打散就一定没有热点,只是减缓。
超过96M,会自动生成下一个region,这两个region都是分布在所有的节点中:是先在一个节点上分裂region,然后根据调度leader才被调度到其他节点,这个过程中就有资源的消耗了。

TiDB 自动 Split 仅保证 Region 不超限,不保证分布均衡。手动 Split + Scatter 可将新 Region 打散到不同 Store,避免写入热点集中在原 Leader 所在节点。

有可能某个频繁的查询的数据刚好都落在了少量的几个region中,因此会有热点

这点我的理解和你一样,现在是我想确认是哪些region产生了热点,这样我才好专门为这些有热点的region再进一步打散,而不是盲目的去见到region就打散。

1、看热力度最直观,根据表和key确定region;
2、看表TIDB_HOT_REGIONS;
3、pt工具查看region topread等;

TIDB_HOT_REGIONS 这张表不知道准不准,因为查出来有很多,我们从中怎么找出对前CPU性能影响最大的那些热点表及region呢

热点打散的主要目的还是为了分散热点,当然你的id可以使用random实现

热点图显示的那些表,我们无法确认它是哪一个节点引起的热点,也有可能这个热点不是最终导致CPU负载高的原因。

磁盘空间问题可以检查下有没有空 Region,用 pd-ctl region check empty-region 查看,手工 merge 掉。另外 GC 时间设置得太短也可能导致空间释放不及时。

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。