一、雪花算法
1、雪花算法简介
SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上是保持自增的。
由于在Java中64bit的整数是long类型,所以在Java中SnowFlake算法生成的id就是long来存储的。
2、雪花算法生成ID的结构
1、1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0。
2、41bit-时间戳,用来记录时间戳,毫秒级。
- 41位可以表示 (2^41-1) 个数字,
- 如果只用来表示正整数(计算机中正数包含0),可以表示的数值范围是:0 至 2^41-1 ,减1是因为可表示的数值范围是从0开始算的,而不是1。
- 也就是说41位可以表示 2^41-1 个毫秒的值,转化成单位年则是69年
3、10bit-工作机器id,用来记录工作机器id。
- 可以部署在 2^10=1024 个节点,包括5位datacenterId和5位workerId
- 5位(bit)可以表示的最大正整数是 2^5-1=31 ,即可以用0、1、2、3、....31这32个数字,来表示不同的datecenterId或workerId
4、12bit-序列号,序列号,用来记录同毫秒内产生的不同id。
- 12位(bit)可以表示的最大正整数是 2^12-1=4095 ,即可以用0、1、2、3、....4094这4095个数字,来表示同一机器同一时间截(毫秒)内产生的4095个ID序号。
3、雪花算法能够保证
(1)所有生成的id按时间趋势递增
(2)整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)
4、雪花算法优缺点
优点:
(1)高性能高可用:生成时不依赖于数据库,完全在内存中生成。
(2)容量大:每秒中能生成数百万的自增ID。
(3)ID自增:存入数据库中,索引效率高。
缺点:
(1)依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能会造成id冲突或者重复。
(2)不一定是全局递增的
5、雪花算法的优化——时钟回拨问题
保存过去一段时间内每一台机器在当前这一毫秒产生的ID的最大值,比如使用Map形式,就是<machine_id,max_id>,这样如果某台机器发生了时钟回拨,直接在这台机器对应的max_id的基础上继续自增生成ID即可。
6、源码
参考:雪花算法的原理和实现Java_雨夜青草的博客-CSDN博客_雪花算法
二、UUID
1、UUID简介
UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID,详情见IETF发布的UUID规范 A Universally Unique IDentifier (UUID) URN Namespace。
2、UUID的优缺点
优点:
(1)性能非常高:本地生成,没有网络消耗。
缺点:
(1)不易于存储:UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用;
(2)信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。
(3)ID作为主键时在特定的环境会存在一些问题,比如做DB主键的场景下,UUID就非常不适用:
1、MySQL官方有明确的建议主键要尽量越短越好[4],36个字符长度的UUID不符合要求。
2、对MySQL索引不利:如果作为数据库主键,在InnoDB引擎下,UUID的无序性可能会引起数据位置频繁变动,严重影响性能。
三、Leaf
参考:Leaf——美团点评分布式ID生成系统 - 美团技术团队
9种分布式ID生成之美团(Leaf)实战_程序员内点事-CSDN博客_leaf 美团