分布式ID方案SnowFlake雪花算法分析
1、算法
SnowFlake算法生成的数据组成结构如下:
在java中用long类型标识,共64位(每部分用-分开):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 0000000000 00
- 1位标识,0表示正数。
- 41位时间戳,当前时间的毫秒减去开始时间的毫秒数。可用 (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年。
- 5位数据中心标识,可支持(1L << 5) = 32个数据中心。
- 5位机器标识,每个数据中心可支持(1L << 5) = 32个机器标识。
- 12位序列号,每个节点每一毫秒支持(1L << 12) = 4096个序列号。
2、Java版本实现
1 |
|
3、难点
Tips: 左移几位,则后面加几个0。
3.1、计算机器标识最多支持的最大正整数
1 | private long workerIdBits = 5L; |
计算过程:
- -1的补码:
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 - -1 左移 5 位,高位溢出,低位补0:
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11100000 - 取反:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00011111 - 转10进制:
16 + 8 + 4 + 2 + 1 = 31
3.2、sequence溢出处理
1 | sequence = (sequence + 1) & sequenceMask; |
计算过程:
假设sequence=4095:
- (4095 + 1) & 4095
- 4096: ……. 00010000 00000000
- 4095: ……. 00001111 11111111
- 按位与 ……. 00000000 00000000
- 最终sequence为0,即sequence发生溢出。
3.3、ID计算
1 | ((timestamp - startEpoch) << timestampShift) | |
计算过程:
- 当前时间的毫秒数-开始时间的毫秒数,结果左移22位
假设:timestamp - startEpoch = 1
二进制: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
左移22位: 00000000 00000000 00000000 00000000 00000000 01000000 00000000 00000000
- dataCenterId左移17位
假设:dataCenterId = 1
二进制: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
左移17位: 00000000 00000000 00000000 00000000 00000000 00000010 00000000 00000000
- workerId左移12位
假设:workerId = 1
二进制: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
左移12位: 00000000 00000000 00000000 00000000 00000000 00000000 00010000 00000000
- 最后的所有结果按位
或
假设:sequence = 1
00000000 00000000 00000000 00000000 00000000 01000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000010 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00010000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000000 00000000 01000010 00010000 00000001
- 结果:
0 - 0000000 00000000 00000000 00000000 00000000 01 - 00001 - 00001 - 0000 00000001
符合SnowFlake算法数据组成结构。
参考
理解分布式id生成算法SnowFlake
Twitter雪花算法SnowFlake算法的java实现