分布式 id 生成器(snowflake,雪花算法)

背景

在某些场景下,需要生成增长ID并且不能重复

snowflake

Snowflake 雪花算法,由Twitter提出并开源,可在分布式环境下用于生成唯一ID的算法。该算法生成的是一个64位的ID,故在Java下正好可以通过8字节的long类型存放。所生成的ID结构如下所示

20240328210209

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

41 bit:表示的是时间戳,单位是毫秒
41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2 ^ 41 - 1 个毫秒值,换算成年就是表示 69 年的时间。

10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10 台机器上,也就是 1024 台机器
10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2 ^ 5 个机房(32 个机房),每个机房里可以代表 2 ^ 5 个机器(32 台机器),也可以根据自己公司的实际情况确定。

12 bit:这个是用来记录同一个毫秒内产生的不同 id
12 bit 可以代表的最大正整数是 2 ^ 12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。

Example-Go

package main

import (
"fmt"

"github.com/bwmarrin/snowflake"
)

func main() {

// Create a new Node with a Node number of 1
node, err := snowflake.NewNode(1)
if err != nil {
fmt.Println(err)
return
}

// Generate a snowflake ID.
id := node.Generate()

// Print out the ID in a few different ways.
fmt.Printf("Int64 ID: %d\n", id)
fmt.Printf("String ID: %s\n", id)
fmt.Printf("Base2 ID: %s\n", id.Base2())
fmt.Printf("Base64 ID: %s\n", id.Base64())

// Print out the ID's timestamp
fmt.Printf("ID Time : %d\n", id.Time())

// Print out the ID's node number
fmt.Printf("ID Node : %d\n", id.Node())

// Print out the ID's sequence number
fmt.Printf("ID Step : %d\n", id.Step())

// Generate and print, all in one.
fmt.Printf("ID : %d\n", node.Generate().Int64())
}