[go 面试] 雪花算法与分布式ID生成

生成全局唯一ID的雪花算法原理

雪花算法是一种用于生成全局唯一ID的算法,最初由Twitter开发,用于解决分布式系统中生成ID的问题。其核心思想是将一个64位的长整型ID划分成多个部分,每个部分用于表示不同的信息,确保了生成的ID在分布式环境下的唯一性。

ID结构

  1. 符号位(1位):始终为0,用于保证ID为正数。
  2. 时间戳(41位):表示生成ID的时间戳,精确到毫秒级。
  3. 工作节点ID(10位):表示生成ID的机器的唯一标识。
  4. 序列号(12位):表示在同一毫秒内生成的多个ID的序列号。

生成步骤

  1. 获取当前时间戳,精确到毫秒级。
  2. 如果当前时间小于上次生成ID的时间,或者在同一毫秒内生成的ID数量超过最大值,等待下一毫秒再继续生成。
  3. 如果当前时间等于上次生成ID的时间,序列号自增1。
  4. 如果当前时间大于上次生成ID的时间,序列号重新从0开始。
  5. 将各个部分的值组合,得到最终的64位ID。

Go实现雪花算法的高并发ID生成器

go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"
)

const (
	workerBits     = 10
	sequenceBits   = 12
	workerMax      = -1 ^ (-1 << workerBits)
	sequenceMask   = -1 ^ (-1 << sequenceBits)
	timeShift      = workerBits + sequenceBits
	workerShift    = sequenceBits
	epoch          = 1609459200000
)

type Snowflake struct {
	mu          sync.Mutex
	lastTime    int64
	workerID    int64
	sequence    int64
}

func NewSnowflake(workerID int64) *Snowflake {
	if workerID < 0 || workerID > workerMax {
		panic(fmt.Sprintf("worker ID must be between 0 and %d", workerMax))
	}
	return &Snowflake{
		lastTime: time.Now().UnixNano() / 1e6,
		workerID: workerID,
		sequence: 0,
	}
}

func (sf *Snowflake) NextID() int64 {
	sf.mu.Lock()
	defer sf.mu.Unlock()

	currentTime := time.Now().UnixNano() / 1e6

	if currentTime < sf.lastTime {
		panic(fmt.Sprintf("clock moved backwards, refusing to generate ID for %d milliseconds", sf.lastTime-currentTime))
	}

	if currentTime == sf.lastTime {
		sf.sequence = (sf.sequence + 1) & sequenceMask
		if sf.sequence == 0 {
			for currentTime <= sf.lastTime {
				currentTime = time.Now().UnixNano() / 1e6
			}
		}
	} else {
		sf.sequence = 0
	}

	sf.lastTime = currentTime

	id := (currentTime-epoch)<<timeShift | (sf.workerID << workerShift) | sf.sequence
	return id
}

func main() {
	sf := NewSnowflake(1) // 假设工作节点ID为1

	for i := 0; i < 10; i++ {
		id := sf.NextID()
		fmt.Println(id)
		time.Sleep(time.Millisecond)
	}
}

高并发下的唯一性和递增性保障

在高并发场景下,保障雪花算法生成的ID唯一性和递增性的关键在于:

  1. 唯一性: 工作节点ID的设置保证了不同节点生成的ID不会冲突。序列号的自增和位运算保证了同一毫秒内生成的ID唯一。
  2. 递增性: 在同一毫秒内生成的多个ID按序列号的递增顺序排列。即使在极端情况下,同一毫秒内生成的ID数量超过了最大值,会等待下一毫秒重新开始,也保证了递增性。

总体来说,雪花算法在高并发下是一个可靠的ID生成方案。它的高性能和低碰撞概率使得它在分布式系统中被广泛应用。

相关推荐
SuperHeroWu73 分钟前
【HarmonyOS 6】UIAbility跨设备连接详解(分布式软总线运用)
分布式·华为·harmonyos·鸿蒙·连接·分布式协同·跨设备链接
2301_7644413310 分钟前
Python构建输入法应用
开发语言·python·算法
杜子不疼.17 分钟前
【探索实战】从0到1打造分布式云原生平台:Kurator全栈实践指南
分布式·云原生
AI科技星20 分钟前
为什么变化的电磁场才产生引力场?—— 统一场论揭示的时空动力学本质
数据结构·人工智能·经验分享·算法·计算机视觉
TheLegendMe1 小时前
贪心+线程安全单例
算法·哈希算法
豐儀麟阁贵2 小时前
8.5在方法中抛出异常
java·开发语言·前端·算法
胖咕噜的稞达鸭2 小时前
算法入门:滑动窗口--->找到字符串中所有的字母异位词,串联所有的子串,最小覆盖子串
数据库·redis·算法
小青龙emmm2 小时前
2025级C语言第二次周测(国教专用)题解
c语言·开发语言·算法
WolfGang0073213 小时前
代码随想录算法训练营Day28 | 509.斐波那契数列、70.爬楼梯、746.使用最小花费爬楼梯
算法
Boop_wu3 小时前
[Java EE] 多线程进阶(JUC)(2)
java·jvm·算法