一、雪花算法介绍

1. 由来

        雪花算法英文名为SnowFlake,故为雪花。最早是 Twitter 公司在其内部用于分布式环境生成唯一 ID

2.作用

        雪花算法可以分布式环境生成全局唯一int64类型id

3. 原理

二、实现

        1.常量定义

const (
	machineBits  = int64(5)  //机器id位数
	serviceBits  = int64(5)  //服务id位数
	sequenceBits = int64(12) //序列id位数

	maxMachineID  = int64(-1) ^ (int64(-1) << machineBits)  //最大机器id
	maxServiceID  = int64(-1) ^ (int64(-1) << serviceBits)  //最大服务id
	maxSequenceID = int64(-1) ^ (int64(-1) << sequenceBits) //最大序列id

	timeLeft    = uint8(22) //时间id向左移位的量
	machineLeft = uint8(17) //机器id向左移位的量
	serviceLeft = uint8(12) //服务id向左移位的量

	twepoch = int64(1667972427000) //初始毫秒,时间是: Wed Nov  9 13:40:27 CST 2022
)

        2.代码


type Worker struct {
	sync.Mutex
	lastStamp  int64
	machineID  int64 //机器id,0~31
	serviceID  int64 //服务id,0~31
	sequenceID int64
}

func NewWorker(machineID, serviceID int64) *Worker {
	return &amp;Worker{
		lastStamp:  0,
		machineID:  machineID,
		serviceID:  serviceID,
		sequenceID: 0,
	}
}

func (w *Worker) GetID() int64 {
	//多线程互斥
	w.Lock()
	defer w.Unlock()

	mill := time.Now().UnixMilli()

	if mill == w.lastStamp {
		w.sequenceID = (w.sequenceID + 1) &amp; maxSequenceID
		//当一个毫秒分配的id数&gt;4096个时,只能等待到下一毫秒去分配。
		if w.sequenceID == 0 {
			for mill &gt; w.lastStamp {
				mill = time.Now().UnixMilli()
			}
		}
	} else {
		w.sequenceID = 0
	}

	w.lastStamp = mill
	//fmt.Println(w.lastStamp - twepoch)
	//fmt.Println((w.lastStamp - twepoch) << timeLeft)
	//fmt.Printf("%bn", (w.lastStamp-twepoch)<<timeLeft)
	id := (w.lastStamp-twepoch)<<timeLeft | w.machineID<<machineLeft | w.serviceID<<serviceLeft | w.sequenceID
	return id
}

三、测试

10000个协程同时请求id:


var work = NewWorker(30, 30)

func main() {
	var wg sync.WaitGroup

	count := 10000
	ch := make(chan int64, count)

	wg.Add(count)
	defer close(ch)
	//并发 countgoroutine 进行 snowFlake ID 生成
	for i := 0; i < count; i++ {
		go func() {
			defer wg.Done()
			id := work.GetID()
			ch <- id
		}()
	}
	wg.Wait()
	m := make(map[int64]int)
	for i := 0; i < count; i++ {
		id := <-ch
		// 如果 map存在为 id 的 key, 说明生成的 snowflake ID 有重复
		_, ok := m[id]
		if ok {
			fmt.Printf("repeat id %dn", id)
			return
		}
		// 将 id 作为 key 存入 map
		m[id] = i
	}
	// 成功生成 snowflake ID
	fmt.Println("All", len(m), "snowflake ID Get successed!")
}

结果

        

参考文献

        最详细的雪花算法讲解,包教包会(go版本)_51CTO博客_雪花算法解析

        雪花算法(SnowFlake)_文丑颜不良啊的博客-CSDN博客_雪花算法

原文地址:https://blog.csdn.net/qq_42170897/article/details/127768047

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_27960.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注