SNOWFLAKE雪花算法
SnowFlake
算法,是 Twitter
开源的分布式id
生成算法。
其核心思想是:使用一个 64 bit
的 long
型的数字作为全局唯一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 bit
里 5 个 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)
}