分布式Id生成策略

本文介绍了几种分布式ID生成的方法:UUID因其字符串长度和非自增特性不适合某些场景;数据库自增ID在高并发下可能压力过大;多主模式虽缓解但仍有扩展性问题;数据库号段模式+内存分配牺牲了自增顺序;Redis的incr命令提供了高性能但需考虑持久化带来的风险。选择适合业务的分布式ID策略至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

​ 哈喽,大家好,上一篇文章洪爵详细讲解了雪花算法,但其实还有其他的分布式Id生成方式,洪爵这里做一个简单的介绍,如果有需要讲详细的,可以私信洪爵哦。

1、UUID

​ 其中一个是比较常见的UUID(Universally Unique Identifier),它有着全球的唯一性,因为生成的Id里是携带了些硬件信息,比如MAC地址等。虽然唯一性很高,并且生成较为简单,但它有个缺点,一个是说它是字符串,并且字符串长度较大存储查询性能不高,第二个是说它不具备主键Id自增的能力

public class Main {
    public static void main(String[] args) {
 System.out.println(UUID.randomUUID().toString().replaceAll("-", ""));
    }
}
//47cac6086e2447598b34e783226b9d5b

2、数据库自增Id

​ 在数据库中维护一个表结构,该表结构有一个使用auto_increment的自增Id,当我们需要一个分布式唯一Id时,就向表中插入一条数据,并且返回它对应的Id,虽然实现很简单,但是也有很大的缺点,当并发访问的时候,很可能打挂数据库,毕竟插入数据等操作都需要进行IO的,MySQL的瓶颈显而易见了。

在这里插入图片描述

3、多主模式数据库自增Id

​ 既然单库单表结构容易被打挂,那么就对它进行一个优化,使用两个节点去生成分布式唯一Id,数据库A从1开始生成,数据库B从2开始生成,每次的步长为2,这样数据库A就只生成奇数的Id,数据库B只生成偶数的Id

当然,这不能从根本上解决问题,因为当并发量上来了,2个节点承受不住崩了怎么办?那就又要增加新的节点,三个节点均匀生成Id,那么就要重新设置步长了,节点A生成1,4,7…,节点B生成2,5,8…,节点C生成3,6,9…等等,并且还需要人工进行调整,万一设置错误还可能导致有重复的唯一Id出现,有很大的风险,不利于后续的扩容,但在一定程度上也解决了单表生成唯一Id的性能问题
在这里插入图片描述

4、数据库号段模式 + 内存分配

​ 在数据库中维护一个Id,当服务器A需要分配一个新的唯一Id时,查询数据库获取到对应的Id,并且设置数据库中的Id = Id + 500(不固定),那么服务器A就能拿这500个唯一Id存放到内存中,进行分配,等待下次用完了这500个Id时再进行获取。这种做法相比于每次要唯一Id时才查询,降低了并发度,但也存在问题,不能保证自增的顺序**,比如说服务器A访问数据库,查询到Id = 100,然后给数据库中的Id设置成600,那么服务器可支配的Id范围为100~599,这个时候服务器B也去访问数据库拿到了Id = 600,给Id设置为1100,服务器B可支配的Id范围为600~1099。那么B服务器无论什么时候进行插入,Id的大小都会比服务器A所拥有的Id要大,所以无法保证自增顺序**。

在这里插入图片描述

5、Redis实现唯一Id

​ 通过Redis的incr命令实现Id自增,Redis基于内存操作比单数据库的性能要高,但也有不足的地方,Redis的持久化是基于AOF和RDB,如果使用的RDB,Redis数据库挂了之后重启,可能会出现Id重复分配的情况

127.0.0.1:6379> set soleId 1
OK
127.0.0.1:6379> incr soleId
(integer) 2

​ 好了,本章节就到这里啦,希望当你需要用到分布式Id时,脑中有更多的方法和策略,选择出最适合你业务场景的实现方式

在这里插入图片描述
愿每个人都能带着怀疑的态度去阅读文章并探究其中原理。

道阻且长,往事作序,来日为章。

期待我们下一次相遇!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KnightHONG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值