在分布式系统,有些数据会存在全局唯一的需求,生成全局唯一的分布式ID也很重要。
全局唯一:最基本的要素
趋势递增:分布式ID用来标识数据的唯一性,往往会被用作主键或者是唯一索引。常用的MySQL InnoDB,使用的索引往往是BTree索引,自增的数据在插入时会有较高的效率。
信息安全:避免恶意用户直接根据自增ID获取数据信息
UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符。UUID是基于当前时间、计数器和硬件标识(比如MAC地址)生成的
优点:
本地生成,不需要远程调用
缺点:
生成结果较长,不适合作为索引
无序的UUID作为主键索引也会严重影响数据插入的效率
基于MAC地址生成的UUID可能会造成MAC地址泄漏
64bit
第一个bit用于表示正数还是负数。作为ID的情况下,这个位置固定为0。
41bit用于表示毫秒级时间戳,可以使用69年。
10bit workerId可以用于表示1024台机器。
12bit用于作为自增序列号
雪花算法理论上的QPS可以到达4096000
优点:
时间在高位,序列号在低位。趋势递增
生成的ID为long类型
不需要依赖数据库等
缺点:
强依赖时钟,时钟回拨会导致发号重复
利用数据库自增ID特性生成ID,每次写入之后获取last insert id。
优点:
实现成本低
有序自增
缺点:
强依赖数据库,且ID生成性能受限于数据库写入的性能
每台机器设置不同的初始值以及指定步长,步长=部署的机器数量。比如2台机器的情况,第一台机器生成的ID是1,3,5,7,第二台生成的是2,4,6,8。
优点:
实现简单
缺点:
步长固定,需要扩容的时候很难处理
每次生成ID都需要读写数据库
批量获取ID,缓存在本地,缓存数据用完之后才会再去获取下一批ID。
优点:
数据库的读写频率从原本的每次获取ID都需要对数据库进行读写,频率降为之前的1/(批量获取ID的size)
ID号码趋势递增
对号段有缓存,即使数据库暂时不可用,ID仍然可以坚持到缓存的号段分配完成
缺点:
ID号码不够随机,可能会泄露发号的数量
号段用完之后还是可能会受到DB读写性能的影响
可以从上面的几种方式,学习到的基本思路是:根据实例唯一标识+时间戳+自增序列号作为分布式ID生成的规则。