开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
我们在一些业务中,如果使用了分库分表,无非就是两种原因:一是单库并发太高,二是数据量太大。
但是我们在分库分表中,会遇到一些问题,最关键的问题就是:ID主键怎么处理,原本的单表自增要变成多表生成不重复ID,这样我们应该怎么操作?
经过一些研究,发现有下面几种方法可以实现:
1.基于数据库ID自增
①就是你在入分表以后的这些业务数据之前,先在一张单表A上面进行一个无意义数据的导入,这个表A中得到的自增ID赋值到你的业务数据的ID,再将其插入到分表中。这样的好处就是简单粗暴,缺点就是单表生成自增ID,要是高并发的话,就会有瓶颈。
②设置数据库sequence 或者表自增字段步长来进行水平伸缩,如下图:
这样的好处就是可以达到性能目标,实现也比较简单,不需要从代码层面去处理id,缺点就是服务节点固定,步长也固定,万一以后要加节点,就很难处理了。
2.本地生成UUID
好处就是本地生成随机的UUID,可以脱离数据库限制,坏处就是UUID太长了,占用数据库空间太大,用它做主键性能太差,如果想要使用这个方案,建议将业务的一些数据拼接起来作为一个全局唯一的ID,这样也是可以的。
3.获取系统时间当做ID
这个就是获取系统当前时间戳即可,但是这样做的最大的问题就是,并发很高的时候,比如一秒并发几千,就有很大概率会有重复ID的情况。
4.雪花算法(Snowflake)
雪花算法的基本构造是这样的:
- 1 bit:不用,为啥呢?因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。
- 41 bit:表示的是时间戳,单位是毫秒。41 bit 可以表示的数字多达
2^41 - 1,也就是可以标识2^41 - 1个毫秒值,换算成年就是表示69年的时间。 - 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10台机器上哪,也就是1024台机器。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表
2^5个机房(32个机房),每个机房里可以代表2^5个机器(32台机器)。 - 12 bit:这个是用来记录同一个毫秒内产生的不同 id,12 bit 可以代表的最大正整数是
2^12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。
雪花算法是目前分布式、高并发场景下id生成最靠谱的算法,所以我建议大家更多关注一下雪花算法是最合适的。
这次分享就到这里了,希望大家给点点关注,感谢~