分布式id生成器
github.com/bwmarrin/snowflake 和 sonyflake
是一个相当轻量化的 snowflake 的 Go 实现。其文档对各位使用的定义如下图所示:

此库和标准的 snowflake 实现方式全完一致,使用也比较简单:
package main
import (
// 示例代码只导入提供核心功能的package,其他内置package自行导入,下同
"github.com/bwmarrin/snowflake"
)
func main() {
node, err := snowflake.NewNode(1)
if err != nil {
println(err.Error())
os.Exit(1)
}
for i := 0; i < 20; i++ {
id := node.Generate()
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())
fmt.Printf("ID Time : %d\n", id.Time())
fmt.Printf("ID Node : %d\n", id.Node())
fmt.Printf("ID Step : %d\n", id.Step())
fmt.Println("---------------------------------------------")
}
}
var (
// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds
// You may customize this to set a different epoch for your application.
Epoch int64 = 1288834974657
// NodeBits holds the number of bits to use for Node
// Remember, you have a total 22 bits to share between Node/Step
NodeBits uint8 = 10
// StepBits holds the number of bits to use for Step
// Remember, you have a total 22 bits to share between Node/Step
StepBits uint8 = 12
)
Epoch为起始时间,NodeBits是实例id的位长,StepBits是自增id的位长。
sonyflake
sonyflake 同样是受 Twitter 的 snowflake 启发而来,但 sonyflake 侧重于多主机/实例的生命周期和性能,所以与 snowflake 使用不同的位分配
sonyflake 的优点和缺点:
- 比 snowflake 更长的生命周期,174年 > 69年
- 能运行在更多的实例上,216 > 210
- 生成 ID 速度比 snowflake 慢,10 毫秒内最多生成 28 个(snowflake 1 毫秒内最多生成 212 个)
sonyflake 在启动阶段需要配置参数:
func NewSonyflake(st Settings) *Sonyflake
Settings数据结构如下:
type Settings struct {
StartTime time.Time
MachineID func() (uint16, error)
CheckMachineID func(uint16) bool
}
StartTime起始时间,默认值为2014-09-01 00:00:00 +0000 UTC
MachineID是一个返回实例 ID 的函数,如果不定义此函外,默认用本机ip 的低16位
CheckMachineID验证实例 ID / 计算机ID 的唯一性,返回true时才创建
package main
import (
"github.com/sony/sonyflake"
)
func getMachineID() (uint16, error) {
var machineID uint16 = 6
return machineID, nil
}
func checkMachineID(machineID uint16) bool {
existsMachines := []uint16{1, 2, 3, 4, 5}
for _, v := range existsMachines {
if v == machineID {
return false
}
}
return true
}
func main() {
t, _ := time.Parse("2006-01-02", "2021-01-01")
settings := sonyflake.Settings{
StartTime: t,
MachineID: getMachineID,
CheckMachineID: checkMachineID,
}
sf := sonyflake.NewSonyflake(settings)
for i := 0; i < 10; i++ {
id, err := sf.NextID()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(id)
}
}

浙公网安备 33010602011771号