snowflake 雪花算法
原生Snowflake算法使用一个64 bit的整型数据,根据当前的时间来生成ID。 原生Snowflake结构如下:
- 因为最高位是标识位,为1表示为负数,所以最高位不使用。
- 41bit 保存时间戳,精确到毫秒。也就是说最大可使用的年限是69年。
- 10bit 的机器位,能部属在1024台机器节点来生成ID。
- 12bit 的序列号,一毫秒最大生成唯一ID的数量为4096个。
原生的Snowflake算法是完全依赖于时间的,如果有时钟回拨的情况发生,会生成重复的ID,市场上的解决方案也是非常多的:
- 最简单的方案,就是关闭生成唯一ID机器的时间同步。
- 使用阿里云的的时间服务器进行同步,2017年1月1日的闰秒调整,阿里云服务器NTP系统24小时“消化”闰秒,完美解决了问题。
- 如果发现有时钟回拨,时间很短比如5毫秒,就等待,然后再生成。或者就直接报错,交给业务层去处理。
- 可以找2bit位作为时钟回拨位,发现有时钟回拨就将回拨位加1,达到最大位后再从0开始进行循环。
个人比较推荐的是最后一个方案
找2bit位作为时钟回拨位,发现有时钟回拨就将回拨位加1,达到最大位后再从0开始进行循环。
go snowflake
GitHub:https://github.com/bwmarrin/snowflake
安装库
1 |
go get github.com/bwmarrin/snowflake |
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package main import ( "fmt" "github.com/bwmarrin/snowflake" ) func main() { // 根据节点数,创建雪花实例 // 假设当前是节点 1 node, err := snowflake.NewNode(1) if err != nil { fmt.Println(err) return } // 生成雪花id id := node.Generate() // 通过不同方式输出id 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()) // 打印雪花id的 timestamp fmt.Printf("ID Time : %d\n", id.Time()) // 打印雪花id的 node number fmt.Printf("ID Node : %d\n", id.Node()) // 打印雪花id的 sequence number fmt.Printf("ID Step : %d\n", id.Step()) // 一步到位输出雪花id fmt.Printf("ID : %d\n", node.Generate().Int64()) } |