分布式Unique ID的生成方法

2017-06-20  本文已影响0人  zhanglbjames

ID生成器的特性

发号器(统一中央发号器)

为了避免频繁请求获取ID,则每一次请求都请求一批ID,留着备用,所以此时ID是准连续的,不同机器之间通过多个高位bit来区分
例如总共ID16位,则每次请求都将获取1000 0000(128)
一共有8个机器,则高3位用来区分不同机器,比如机器A分配的高位为001,则每一请求10000000(2的7次方个128个ID),则取走的范围为:0010 0000 0000 0000 ~ 0010 0000 0111 1111,下一次取走
0010 0000 1000 0000 ~ 0010 0000 1111 1111

UUID本地生成

UUID 128位

实际上,UUID一共有多种算法,能用于TraceId的是:

然后是Version1,严格守着原来各个位的规矩:
因为时间戳有满满的60bit,所以可以尽情花,以100纳秒为1,从1582年10月15日算起(能撑3655年,真是位数多给烧的,1582年有意思么)
节点标识也有48bit,一般用MAC地址表达,如果有多块网卡就随便用一块。如果没网卡,就用随机数凑数,或者拿一堆尽量多的其他的信息,比如主机名什么的,拼在一起再hash一把。
顺序号这16bit则仅用于避免前面的节点标示改变(如网卡改了),时钟系统出问题(如重启后时钟快了慢了),让它随机一下避免重复。
但好像Version 1就没考虑过一台机器上起了两个进程这类的问题,也没考虑相同时间戳的并发问题,所以严格的Version1没人实现,接着往下看各个变种吧。

先说Version4,这是最暴力的做法,也是JDK里的算法,不管原来各个位的含义了,除了少数几个位必须按规范填,其余全部用随机数表达。
JDK里的实现,用 SecureRandom生成了16个随机的Byte,用2个long来存储。记得加-Djava.security.egd=file:/dev/./urandom,否则会锁住程序等噪音。

本地64位ID生成

划分命名空间本地并行生成

将机器MAC地址和进程号进行Hash作为高位,然后时间戳(秒级别)作为中位,然后同一时间(1s内)内的自增序列
所以(20-24bit)机器Hash + 时间戳(24-25bit)+ (16-17bit自增序列)

参考链接
https://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=2659598286&idx=1&sn=3172172ccea316b0ed83429ae718b54d&chksm=8be9eadcbc9e63caa10d708274b4fa34ceffa416ef4527e10e6b7a1a2d2f32cf8592d65bf728

上一篇下一篇

猜你喜欢

热点阅读