方案汇总:
- UUID:
结合机器的网卡(基于名字空间/名字的散列值MD5/SHA1)、当地时间(基于时间戳&时钟序列)、一个随记数来生成UUID。结构: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
优点:结合机器的网卡(基于名字空间/名字的散列值MD5/SHA1)、当地时间(基于时间戳&时钟序列)、一个随记数来生成UUID。结构: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
缺点:① UUID太长。
② 信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露。
③ 无序查询效率低:由于生成的UUID是无序不可读的字符串,所以其查询效率低 - 数据库自增
使用数据库的id自增策略,数据库进行水平拆分,每个数据库设置不同的初始值和相同的自增步长
优点:
使用数据库的id自增策略,数据库进行水平拆分,每个数据库设置不同的初始值和相同的自增步长
缺点:① 方案实现复杂
②扩容复杂
③高可用问题,数据库故障后不可使用。
④ 存在数据泄露风险 - 号段模式
每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力
优点:
每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力
缺点:ID号码不够随机,能够泄露发号数量的信息,不太安全
TP999数据波动大
DB宕机会造成整个系统不可用
- Redis
Redis的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的
优点:① 不依赖于数据库,灵活方便,且性能优于数据库。
② 数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:① 如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。
② 需要编码和配置的工作量比较大。
-
雪花算法
优点:
①整体上按照时间按时间趋势递增。
②全局唯一(由数据中心标识ID、机器标识ID作区分) ③本地生成,不依赖db,中间件,高性能。
缺点:
①强依赖于时间,发生时钟回拨,可能会引起ID重复。
② 天然并发限制。
Snowflake 实现的难点? - 百度UidGenerator
默认实现DefaultUidGenerator
时钟回拨问题及并发限制问题解决
CachedUidGenerator-buffer初始化
CachedUidGenerator-buffer填充uid
•workerId:UidGenerator的workerId在实例每次重启时初始化,且就是数据库的自增ID,从而完美的实现每个实例获取到的workerId不会有任何冲突。解决了服务重启大步长时钟回拨引发的问题。
•天然并发限制:UidGenerator不再在每次取ID时都实时计算分布式ID,而是利用RingBuffer数据结构预先生成若干个分布式ID并保存。QPS可达600万。
7. 美团leaf-snowflake
Leaf-snowflake启动步骤
弱依赖 ZooKeeper
除了每次会去ZK 拿数据以外,也会在本机文件系统上缓存一个 workerID 文件。当 ZooKeeper 出现问题,恰好机器出现问题需要重启时,能保证服务能够正常启动。这样做到了对三方组件的弱依赖
时钟回拨
优点:
缺点:
- workerId不能重复使用,可能会超过1024
- 时钟回拨问题只是提供了方案,代码层面并未提供
zk,成本较高 - 存在天然并发限制
- 需要独立部署,依赖zk,成本较高
8、其他
思路:• ip 累加、 workerId 重复后、获取随机 workerId• 依赖jimdb
bit 位设计 -
沿用snowflake方案bit位设计
1+41+10+12参考文献:
https://github.com/Meituan-Dianping/Leaf
https://github.com/baidu/uid-generator