雪花算法id会造成热点吗

目前系统中使用的都是雪花id,作为主键,如果迁移到tidb,以后还使用雪花id,会造成热点问题吗

看你是怎么雪花的。不过mysql的最佳实践到tidb肯定有写入热点。

mysql的主键要尽可能的递增,减少B+树平衡次数。tidb要求主键尽可能的随机,让写分布在多个region上。

如果你的雪花把快速递增的位置调整到前面,那在tidb就是不错的实践。

具体可以看看uuid的最佳实践,道理是相通的。
mysql中uuid推荐使用swap_flag,tidb则是不推荐的。

UUID_TO_BIN() 函数可以接收一个参数 (UUID) 或两个参数(第一个为 UUID,第二个为 swap_flag )。建议不要在 TiDB 中设置 swap_flag ,以避免出现热点问题。

https://docs.pingcap.com/zh/tidb/stable/uuid#uuid-概述

2 个赞

必须是随机数才可以尽量避免吧

按tidb最佳实践使用,不会有热点

分区的规则是什么,和这个有关系

那在迁移过程中没办法改id啊,表之间都有关联的,有什么好点方案没

解决写热点就2种方案。

1,聚簇索引表+auto_random主键

https://docs.pingcap.com/zh/tidb/stable/troubleshoot-hot-spot-issues#使用-auto_random-处理自增主键热点表

2,非聚簇索引表+shade_row_id_bits

https://docs.pingcap.com/zh/tidb/stable/troubleshoot-hot-spot-issues#使用-shard_row_id_bits-处理热点表

非聚簇索引表不依赖主键是什么类型的,但是因为这个时候表的row_id不是主键,而主键是一条单独的唯一索引,所有基于主键查询都会多一次回表。插入性能和根据主键的查询性能都会有所下降。

递增的id都会有热点问题, 建议在分区上打散一下region
比如对雪花算法id做hash算法分成1024个物理小表,region上会有一定的打散
现有系统要改id肯定不好改了

1 个赞

最佳实践肯定还是随机id,然后水平扩容实例即可, 简单便捷, 业务规定上必须要自增的,雪花算法这种那就只能通过表分区来打散region

首先很感谢您的答复,我的场景是这样的,是迁移实时数据,这些数据迁移完后可能还要用id做增删改查,比如表A的主键ID是表B的一个外键,改id不现实了,怎么尽可能在迁移的时候打散

你这种情况就用第二种方法吧。

非聚簇索引表+shade_row_id_bits+pre_split_regions.

CREATE TABLE t
(a BIGINT, b VARCHAR(255),
PRIMARY KEY(a, b) /*T![clustered_index] NONCLUSTERED */));

建表语句改一下,把加粗的部分加上。

8.5版本可以全局设置shade_row_id_bits和pre_split_regions。

https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_shard_row_id_bits-从-v840-版本开始引入

https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_pre_split_regions-从-v840-版本开始引入

shade_row_id_bits=pre_split_regions=2,就等于你的非聚簇索引表建表的时候就被预分裂成4个region了。
这个数值是2的指数。当shade_row_id_bits=pre_split_regions=4的时候就是分成16个region。
要担心写热点,不妨分的大一点,看你tikv的个数,分到8/16都可以。导入的时候也可以观察一下,只要是tikv的写入都是一起上升的就行。没有明显的1个tikv忙的要死,其他的tikv都在围观就行。

1 个赞

表分区实际上是拆分成了不同的物理’小表’,不同的物理小表有不同的Region.
表分区最大只能分1024个物理小表,如果数据量很大百亿级别情况下可能会不够用,实际上有点治标不治本, 自增id,对于有历史冷热数据的情况下, 新数据都是插入最后的region中的, 历史数据不再访问,也就是前面的region不再访问, 访问的都是后面新增的region这块tikv,一样有热点问题,特别是日志表,订单表这种,数据增长到一定规模的时候就不太适用

同样建立索引的时候,也会有热点问题, 比如索引字段也是递增的,你的sql使用了这个索引,也会造成查询的热点

主键:写入时,数据会根据主键进行分布。如果主键是自增的,容易导致写入集中在某个 Region,形成热点。
索引:索引的建立会根据索引值进行分布,索引热点影响的是查询,但最终还是依赖于主键来确定数据的存储位置。

开放给toC端的业务谨慎用自增索引,会查询热点,非要使用的话,要加缓存什么的,不能次次请求都落到库,不然大并发场景下,热点直接给库tikv的这个单节点干爆

根据预计的数据量 优化 shade_row_id_bits 和 pre_split_regions 这两个参数。

随机生成可以,避免热点数据

会造成热点的,因为雪花算法是一直持续递增的状态(虽然不连续)。我有一个想法就是新建一个主键 AUTO_RANDOM 然后原来 雪花算法的id 字段 保留并做一个 唯一索引。后续依然通过雪花算法发号,存入雪花算法id对应的字段里

1 个赞