Go雪花算法的作用領域及實現(xiàn)方法示例
什么是雪花算法
雪花算法(Snowflake)是Twitter開源的一種分布式系統(tǒng)唯一ID生成策略,其核心思想是利用41位作為毫秒數(shù),5位作為數(shù)據(jù)中心的ID,5位作為機器ID,12位作為毫秒內(nèi)的序列號,這樣可以保證每毫秒內(nèi)可以產(chǎn)生多達4096個ID,整個結構如下:1位標識位 + 時間戳41位 + 數(shù)據(jù)中心5位 + 機器5位 + 序列號12位。這種算法可以保證全局唯一性。
雪花算法的作用領域
雪花算法主要用于分布式系統(tǒng)或大型并發(fā)系統(tǒng)中,為了解決全局唯一標識符(ID)的生成問題。這些領域包括但不限于:
- 訂單號生成系統(tǒng)
- 數(shù)據(jù)庫的主鍵生成
- 分布式緩存中的key生成
- 分布式系統(tǒng)中數(shù)據(jù)的唯一性確認
- 在大型互聯(lián)網(wǎng)或者中型軟件系統(tǒng)中,生成全局唯一ID的場景等。
Go如何實現(xiàn)雪花算法
方式一:引入三方庫
引入包
go get -u github.com/bwmarrin/snowflake
實現(xiàn)代碼
package main
import (
"fmt"
"github.com/bwmarrin/snowflake"
)
func main() {
node, err := snowflake.NewNode(1)
if err != nil {
fmt.Println(err)
return
}
id := node.Generate()
fmt.Println(id)
}這個例子先創(chuàng)建了一個snowflake節(jié)點,然后生成一個ID。
注意:這個庫所用的雪花算法有些許與原始算法對位寬的分配有所不同,Twitter版本是 1位標識 + 時間戳41位 + 數(shù)據(jù)中心5位 + 機器5位 + 序列號12位。而bwmarrin庫版本是 snowflake.NodeBits=10,snowflake.StepBits=12,即數(shù)據(jù)中心和機器ID共占10位,序列號占12位。
方式二:實現(xiàn)源碼
package main
import (
"fmt"
"sync"
"time"
)
const (
epoch int64 = 1526285084378 // 設置起始時間(這里一般是項目上線時間)
timestampBits = uint(41) // 時間戳占41位
machineBits = uint(5) // 機器位占5位
sequenceBits = uint(12) // 序列號占12位
machineMax = int64(-1) ^ (int64(-1) << machineBits) // 機器標識最大值
sequenceMask = int64(-1) ^ (int64(-1) << sequenceBits) // 序列號最大值
machineShift = sequenceBits // 機器碼左移位數(shù)
timestampShift = machineBits + sequenceBits // 時間戳左移位數(shù)
)
var (
machineID int64
sequence int64
lastTimestamp int64
lock sync.Mutex
)
func NextID() int64 {
lock.Lock()
defer lock.Unlock()
timestamp := time.Now().UnixNano() / int64(time.Millisecond)
if timestamp < lastTimestamp {
panic("invalid timestamp")
}
if timestamp == lastTimestamp {
sequence = (sequence + 1) & sequenceMask
if sequence == 0 {
timestamp = waitNextMillisecond(lastTimestamp)
}
} else {
sequence = 0
}
lastTimestamp = timestamp
return ((timestamp - epoch) << timestampShift) | (machineID << machineShift) | sequence
}
func waitNextMillisecond(last int64) int64 {
timestamp := time.Now().UnixNano() / int64(time.Millisecond)
for timestamp <= last {
timestamp = time.Now().UnixNano() / int64(time.Millisecond)
}
return timestamp
}
func main() {
fmt.Println(NextID())
}注意,這只是一個簡化版的雪花算法。在生產(chǎn)環(huán)境中,你需要處理亂序和時鐘回撥問題,以及考慮數(shù)據(jù)中心和機器標識的生成問題。此外,epoch時間需要你自己設定,一般設置為系統(tǒng)上線的時間。
以上就是Go雪花算法的作用領域及實現(xiàn)方法示例的詳細內(nèi)容,更多關于Go 雪花算法的資料請關注腳本之家其它相關文章!
相關文章
golang 刪除切片的某個元素及剔除切片內(nèi)的零值方式
這篇文章主要介紹了golang 刪除切片的某個元素及剔除切片內(nèi)的零值方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
go語言規(guī)范RESTful?API業(yè)務錯誤處理
這篇文章主要為大家介紹了go語言規(guī)范RESTful?API業(yè)務錯誤處理方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
go語言 xorm框架 postgresql 的用法及詳細注解
這篇文章主要介紹了go語言 xorm框架 postgresql 的用法及詳細注解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12

