首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >如何通过 go 语言实现雪花算法?

如何通过 go 语言实现雪花算法?

作者头像
程序猿川子
发布于 2025-06-09 17:04:05
发布于 2025-06-09 17:04:05
1.3K0
举报

在 Go 语言中,可以通过实现雪花算法(Snowflake)来生成分布式唯一ID。雪花算法是 Twitter 提出的一种生成分布式唯一ID的算法,其核心思想是将一个64位的ID划分为多个部分,分别表示时间戳、机器ID和序列号。

以下是雪花算法的 Go 语言实现:


1. 雪花算法结构

雪花算法的64位ID结构如下:

scss

| 1 bit (未使用) | 41 bits (时间戳) | 10 bits (机器ID) | 12 bits (序列号) |

  • 时间戳:41位,表示从某个起始时间到当前时间的毫秒数。
  • 机器ID:10位,用于标识不同的机器或节点。
  • 序列号:12位,用于同一毫秒内生成多个ID。

2. Go 实现代码

以下是雪花算法的 Go 实现:

go

package main import ( "errors" "fmt" "sync" "time" ) const ( // 定义各部分的位数 epoch int64 = 1609459200000 // 起始时间:2021-01-01 00:00:00 UTC timestampBits uint8 = 41 machineIDBits uint8 = 10 sequenceBits uint8 = 12 // 定义最大值 maxMachineID int64 = -1 ^ (-1 << machineIDBits) maxSequence int64 = -1 ^ (-1 << sequenceBits) // 定义位移 timestampShift = machineIDBits + sequenceBits machineIDShift = sequenceBits ) // Snowflake 结构体 type Snowflake struct { mutex sync.Mutex lastStamp int64 machineID int64 sequence int64 } // NewSnowflake 创建一个 Snowflake 实例 func NewSnowflake(machineID int64) (*Snowflake, error) { if machineID < 0 || machineID > maxMachineID { return nil, errors.New("machine ID out of range") } return &Snowflake{ lastStamp: 0, machineID: machineID, sequence: 0, }, nil } // NextID 生成下一个唯一ID func (s *Snowflake) NextID() int64 { s.mutex.Lock() defer s.mutex.Unlock() // 获取当前时间戳 currentStamp := time.Now().UnixMilli() // 如果当前时间戳小于上次生成ID的时间戳,说明时钟回拨 if currentStamp < s.lastStamp { panic("clock moved backwards") } // 如果是同一毫秒内生成的ID,则递增序列号 if currentStamp == s.lastStamp { s.sequence = (s.sequence + 1) & maxSequence // 如果序列号溢出,则等待下一毫秒 if s.sequence == 0 { for currentStamp <= s.lastStamp { currentStamp = time.Now().UnixMilli() } } } else { // 如果不是同一毫秒,则重置序列号 s.sequence = 0 } // 更新上次生成ID的时间戳 s.lastStamp = currentStamp // 生成ID id := ((currentStamp - epoch) << timestampShift) | (s.machineID << machineIDShift) | s.sequence return id } func main() { // 创建一个 Snowflake 实例,机器ID为 1 snowflake, err := NewSnowflake(1) if err != nil { panic(err) } // 生成10个唯一ID for i := 0; i < 10; i++ { id := snowflake.NextID() fmt.Println(id) } }


3. 代码说明

  • 起始时间:epoch 是算法的起始时间,可以根据需要调整。
  • 机器ID:machineID 用于标识不同的机器或节点,必须在 [0, maxMachineID] 范围内。
  • 序列号:sequence 用于同一毫秒内生成多个ID,范围为 [0, maxSequence]。
  • 线程安全:使用 sync.Mutex 确保并发安全。
  • 时钟回拨处理:如果当前时间戳小于上次生成ID的时间戳,说明时钟回拨,直接抛出异常。

4. 示例输出

运行上述代码,会生成类似以下的唯一ID:

6928334669447168 6928334669447169 6928334669447170 6928334669447171 6928334669447172 6928334669447173 6928334669447174 6928334669447175 6928334669447176 6928334669447177


5. 优点

  • 高性能:生成ID的速度非常快。
  • 分布式:通过机器ID支持分布式部署。
  • 有序性:ID 按时间递增,适合作为数据库主键。

6. 注意事项

  • 机器ID分配:确保每台机器的 machineID 唯一。
  • 时钟同步:确保各机器的时钟同步,避免时钟回拨问题。
  • ID长度:生成的ID是64位整数,适合大多数场景。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 雪花算法结构
  • 2. Go 实现代码
  • 3. 代码说明
  • 4. 示例输出
  • 5. 优点
  • 6. 注意事项
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档