雪花算法原理

雪花算法

  • 雪花算法是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。欢迎来撩!

posted @ 2022-08-20 20:26  敬敬不想造轮子  阅读(572)  评论(0编辑  收藏  举报