雪花算法概述
snowflake 是 twitter 开源的分布式ID生成算法,其核心思想为,一个long型的ID:
- 41 bit 作为毫秒数 - 41位的长度可以使用69年
- 10 bit 作为机器编号 (5个bit是数据中心,5个bit的机器ID) - 10位的长度最多支持部署1024个节点
- 12 bit 作为毫秒内序列号 - 12位的计数顺序号支持每个节点每毫秒产生4096个ID序号
代码实现
package main
import (
"fmt"
"sync"
"time"
)
// 服务上线时间毫秒时间戳
const startTime = 1698734492000
// SnowflakeId组成:timestamps[41bits] workId[10bits] seqId[12bits]
type snowflakeIdWorker struct {
sync.Mutex
workId int //[0,1024)
lastTms int64
seqInTms int //[0,4096)
}
func NewSnowflakeIdWorker(workId int) *snowflakeIdWorker {
return &snowflakeIdWorker{
Mutex: sync.Mutex{},
workId: workId,
lastTms: 0,
seqInTms: 0,
}
}
func (p *snowflakeIdWorker) GetUUID() int64 {
p.Lock()
defer p.Unlock()
nowTms := time.Now().UnixNano() / 1e6
if nowTms == p.lastTms {
p.seqInTms = (p.seqInTms + 1) & (1<<12 - 1)
if p.seqInTms == 0 {
for nowTms == p.lastTms {
nowTms = time.Now().UnixNano() / 1e6
}
}
} else {
p.seqInTms = 4090
p.lastTms = nowTms
}
return (nowTms - startTime)<<22 | int64(p.workId)<<12 | int64(p.seqInTms)
}
func main() {
worker := NewSnowflakeIdWorker(1)
for i := 0; i < 10000; i++ {
a := worker.GetUUID()
b := fmt.Sprintf("%b", a)
fmt.Println("a", a, "b", b, "len(b):", len(b))
}
}