雪花算法原理
雪花算法
- 雪花算法是Twitter开源的分布式ID生成算法
雪花算法我们在工作中经常使用到,大多数用来表示数据库中的主键id,我们应该不仅仅知道雪花算法是什么,还应该知道他的原理。
问题
- 雪花算法是如何生成的?
- 为什么他在分布式的场景下不会重复?
原理解析
雪花算法生成的id是由一个64bit(二进制位)的long类型的整数
64个二进制位分为四个部分:
-
第一部分:就1bit,始终为0,没有意义,因为在二进制中第一位为1那就是负数
-
第二部分:41bit 时间戳位,引入时间戳的因素这样就可以保证生成的数一直在递增
-
第三部分:10bit,其实又分为两部分,5bit为数据中心id(可以理解为机房),5bit为机器id。这样就可以是分布式的了,每个机房的每个机器生成的id都不一样,不会发生冲突。
-
第四部分:12bit,这是为了防止同一个毫秒在同一个机器上产生的id有冲突。
分析源码
public synchronized long nextId() {
long timestamp = this.genTime();
if (timestamp < this.lastTimestamp) {
throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", new Object[]{this.lastTimestamp - timestamp}));
} else {
if (this.lastTimestamp == timestamp) {
this.sequence = this.sequence + 1L & 4095L;
if (this.sequence == 0L) {
timestamp = this.tilNextMillis(this.lastTimestamp);
}
} else {
this.sequence = 0L;
}
this.lastTimestamp = timestamp;
return timestamp - this.twepoch << 22 | this.dataCenterId << 17 | this.workerId << 12 | this.sequence;
}
}
这是hutool的Snowflake
雪花算法工具类
- 第二行代码,获取当前时间的毫秒数
- 第三行,判断当前时间是否小于上次最后生成的时间,这是防止时间回拨,会出现重复id
- 第六行代码判断,如果当前时间毫秒数和上次最后生成的毫秒数一样,这样客气确定,这是在同一毫秒生成的id,将sequence进行一个递增操作,当然如果递增到12bit的最大值时说明这个毫秒内生成的id已达到上限,会进行等待下个毫秒进行生成
- 第15行,把当前毫秒给到最后的生产毫秒
- 第16行,是生产雪花算法id的最重点的地方,
twepoch
是其实点,因为时间戳就41bit总有用完的时候,这样为了节省空间可以设置一个起始点,然后把这个差值进行向左位移22位,就是时间戳的位置啦,其他同理,或运算相当于把几段拼接在一起了,这是位运算的基础。
大致其实还是蛮简单的哈!
最后,本人能力有限!如果有错误,或者有疑问可以联系我哦!qq:1126184155。欢迎来撩!