SNOWFLAKE雪花算法

SnowFlake 算法,是 Twitter 开源的分布式id 生成算法。
其核心思想是:使用一个 64 bitlong 型的数字作为全局唯一id
在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增

– 第一个部分,是 1 个 bit:0,这个是无意义的。
– 第二个部分是 41 个 bit:表示的是时间戳。
– 第三个部分是 5 个 bit:表示的是机房 id,10001。
– 第四个部分是 5 个 bit:表示的是机器 id,1 1001。
– 第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号

(1)第一位为什么不用?

因为二进制里第一个 bit 为如果是 1,那么都是负数,但我们生成的id 都是正数,所以第一个 bit都是 0。

(2)41 bit表示的是时间戳(单位是毫秒)。

41 bit可以表示的数字多达2^41 - 1=2199,023,255,551,也就是可以标识 2 ^ 41 - 1个毫秒值,换算成年,表示 69 年时间。

(3)10 bit:记录工作机器 id,

代表的是这个服务最多可以部署在 2^10 台机器上,也就是 1024 台机器

但是 10 bit5 个 bit 代表机房id,5 个 bit 代表机器 id。意思就是最多代表 2 ^ 5 =32个机房,每个机房里可以有 2 ^ 5 = 32个机器),也可以根据实际情况确定。

(4)12 bit:这个是用来记录同一个毫秒内产生的不同 id。

12 bit 可以代表的最大正整数是 2 ^ 12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的4096 个不同的 id。
那计算一下:同一毫秒的ID数量=1024×4096=4194304

实现

https://github.com/bwmarrin/snowflake

demo

func Init(startTime string, machineId int64) (err error) {
    var st time.Time
    st, err = time.Parse("2006-01-02", startTime)
    if err != nil {
        return
    }
    snowflake.Epoch = st.UnixNano() / 1000000
    node, err = snowflake.NewNode(machineId)
    return
}

func GenId() int64 {
    return node.Generate().Int64()
}

func main() {
    if err := Init("2021-12-02", 1); err != nil {
        fmt.Println("init failed", err)
        return
    }
    id := GenId()
    fmt.Println(id)
}
分类: go

0 条评论

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

ICP备案号: 辽ICP备20003309号