Golang生成18位雪花ID算法

请问在Golang中如何实现生成18位雪花ID的算法?希望了解具体的代码实现和原理,包括时间戳、机器ID和序列号等部分的分配方式。另外,这种算法在高并发场景下是否会出现ID冲突?有没有性能优化的建议?

2 回复

可以使用SonyFlake或自定义算法生成18位雪花ID。示例:

import "github.com/sony/sonyflake"

func main() {
    flake := sonyflake.NewSonyflake(sonyflake.Settings{})
    id, _ := flake.NextID() // 返回64位整数,可转为18位字符串
}

或自定义实现,结合时间戳、机器ID和序列号。

更多关于Golang生成18位雪花ID算法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,可以使用雪花算法(Snowflake)生成18位唯一ID。雪花ID结构通常包括时间戳、机器ID和序列号,确保分布式环境下生成的ID唯一且有序。

以下是Go实现示例:

package main

import (
	"errors"
	"sync"
	"time"
)

// Snowflake 结构体
type Snowflake struct {
	mu            sync.Mutex
	lastTimestamp int64
	machineID     int64
	sequence      int64
}

// 定义常量(根据需求调整位数)
const (
	machineIDBits  = 5  // 机器ID占5位
	sequenceBits   = 12 // 序列号占12位
	machineIDMax   = -1 ^ (-1 << machineIDBits)
	sequenceMask   = -1 ^ (-1 << sequenceBits)
	timeShift      = machineIDBits + sequenceBits
	machineIDShift = sequenceBits
)

// NewSnowflake 初始化雪花算法实例
func NewSnowflake(machineID int64) (*Snowflake, error) {
	if machineID < 0 || machineID > machineIDMax {
		return nil, errors.New("machine ID out of range")
	}
	return &Snowflake{
		machineID: machineID,
	}, nil
}

// Generate 生成ID
func (s *Snowflake) Generate() int64 {
	s.mu.Lock()
	defer s.mu.Unlock()

	now := time.Now().UnixNano() / 1e6 // 毫秒时间戳

	if now == s.lastTimestamp {
		s.sequence = (s.sequence + 1) & sequenceMask
		if s.sequence == 0 {
			for now <= s.lastTimestamp {
				now = time.Now().UnixNano() / 1e6
			}
		}
	} else {
		s.sequence = 0
	}

	s.lastTimestamp = now

	return (now << timeShift) | (s.machineID << machineIDShift) | s.sequence
}

// 使用示例
func main() {
	sf, _ := NewSnowflake(1) // 机器ID设为1
	id := sf.Generate()
	println(id) // 输出18位数字ID
}

关键说明

  1. 位数分配:时间戳(41位,约69年)、机器ID(5位,32台机器)、序列号(12位,每毫秒4096个ID)。
  2. 线程安全:使用互斥锁确保并发安全。
  3. 时间回拨处理:示例中未处理时钟回拨,生产环境需增加相关逻辑。
  4. 调整参数:可根据需求调整各部分的位数分配。

运行此代码将生成一个18位的唯一ID,适用于分布式系统场景。

回到顶部