IdGenerator SnowFlake 雪花演算法 原生多語言版本 頂尖優化 超強效能
介紹
1.用一種全新的雪花漂移演算法,讓ID更短、生成速度更快,
2.核心在于縮短ID長度的同時,還能擁有極高瞬時并發處理量(保守值 50W/0.1s),
3.原生支持 C#/Java/Go/Rust/C 等語言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等語言多執行緒安全呼叫庫(FFI),
技術支持
開源地址:https://gitee.com/yitter/idgenerator
QQ群:646049993
需求來源
1.作為架構設計的你,想要解決資料庫主鍵唯一的問題,特別是在分布式系統多資料庫的時候,
2.你希望這個主鍵是用最少的存盤空間,索引速度更快,Select、Insert 和 Update 更迅速,
3.你要考慮在分庫分表(合庫合表)時,主鍵值可直接使用,并能反映業務時序,
4.如果這樣的主鍵值太長,超過前端 JS Number 型別最大值,須把 Long 型轉換為 String 型,你會覺得有點沮喪,
5.哪怕 Guid 能自增,但占用空間大,索引速度慢,所以你也不想用它,
6.你的應用實體可能超過50個,每個并發請求可達10W/s,
7.在容器環境部署應用(水平擴展、自動伸縮),
8.你希望系統運行 100 年以上,
傳統演算法問題
1.生成的ID太長,
2.瞬時并發量不夠,
3.不能解決時間回撥問題,
4.不支持后補生成前序ID,
5.依賴外部存盤系統,
新演算法特點
1.整形數字,隨時間單調遞增(不一定連續),長度更短,用50年都不會超過 js Number型別最大值,(默認配置 WorkerId 是6bit,自增數是6bit)
2.速度更快,是傳統雪花演算法的2-5倍,0.1秒可生成50萬個,(i7筆記本,默認演算法配置6bit+6bit)
3.支持時間回撥處理,比如服務器時間回撥1秒,本演算法能自動適應生成臨界時間的唯一ID,
4.支持手工插入新ID,當業務需要在歷史時間生成新ID時,用本演算法的預留位能生成5000個每秒,
5.漂移時能外發通知事件,讓呼叫方確切知道演算法漂移記錄,Log并發呼叫量,
6.不依賴任何外部快取和資料庫,(當然 WorkerId 須由外部指定)
性能資料
(引數:10位自增序列,1000次漂移最大值)
| 連續請求量 | 5K | 5W | 50W |
|---|---|---|---|
| 傳統雪花演算法 | 0.0045s | 0.053s | 0.556s |
| 雪花漂移演算法 | 0.0015s | 0.012s | 0.113s |
效果
1.js Number 型別最大數值:9007199254740992,本演算法在保持并發性能(5W+/0.01s)和最大64個 WorkerId(6bit)的同時,能用70年才到 js Number Max 值,
2.增加WorkerId位數到8bit(256節點)時,15年達到 js Number Max 值,
3.極致性能:500W/s~3000W/s,
4.所有測驗資料均基于8代低壓i7計算,
生成的ID
默認配置:
WorkerIdBitLength = 6 (最多64個作業節點)
SeqBitLength = 6
ID示例(基于默認配置):
129053495681099 (本演算法運行1年)
387750301904971 (運行3年)
646093214093387 (運行5年)
1292658282840139 (運行10年)
9007199254740992 (js Number 最大值)
165399880288699493 (普通雪花演算法生成的ID)
本演算法生成的 ID 值,是 js Number 最大值的 1%-10%,是普通雪花演算法值的千分之一,而計算能力卻超過普通雪花演算法,
適用范圍
1.小型、中型、大型需要全域唯一Id(不用Guid)的專案,
2.分布式專案,
3.不想將 Long 型轉 String 給前端用的專案,(若前端支持bigint,則可不轉型別)
如何處理時間回撥
1.當發生系統時間回撥時,演算法采用過去時序的預留序數生成新的ID,
2.默認每秒生成100個(速度可調整),
3.回撥生成的ID序號,默認靠前,也可以調整為靠后,
4.允許時間回撥至本演算法預設基數(引數可調),
能用多久
1.在默認配置下,ID可用 71000 年不重復,
2.在支持 1024 個作業節點時,ID可用 4480 年不重復,
3.在支持 4096 個作業節點時,ID可用 1120 年不重復,
4.以上所有作業節點,均擁有 50W/0.1s 瞬時處理速度,
默認配置
1.WorkerIdBitLength=6,能支持64個 WorkerId,編號0~63,
2.可通過減少 WorkerIdBitLength 到1~4(為4時最大支持WorkerId為2^4=16個),以減少Id長度,
3.SeqBitLength=6,能支持每秒并發5W請求時,平均處理速度不超過 0.005 s,(不同語言略有差別,最高性能不超過0.002s,平均不超過0.005s)
4.可通過增加 SeqBitLength,支持更高的每秒并發數,默認配置能很高效地支持每秒 5W 并發請求,若要求更高,可適當增加 SeqBitLength 到 8~16,但這將增加Id長度,
★★集成建議★★
常規集成
1.用單例模式呼叫,外部集成方使用更多的實體并行呼叫本演算法,不會增加ID產出效能,因為本演算法采用單執行緒模式生成ID,
2.指定唯一的 WorkerId,必須由外部系統確保 WorkerId 的全域唯一性,并賦值給本演算法入口方法,
3.例外處理,本演算法內部會拋出所有 Exception,外部系統應該 catch 相關資訊并做好應對處理,以免引發更大的系統崩潰,
4.認真理解 IdGeneratorOptions 的定義,這對集成和使用本演算法有幫助,
5.使用雪花漂移演算法,雖然代碼里包含了傳統雪花演算法的定義,并且你可以在入口處指定(Method=2)來啟用傳統演算法,但仍建議你使用雪花漂移演算法(Method=1,默認的),畢竟它具有更好的伸縮力和更高的性能,
6.輕易不要修改核心演算法,本演算法內部引數較多,邏輯較為復雜,在你尚未掌握核心邏輯時,請勿嘗試修改核心代碼且用于生產環境,除非通過大量細致、科學的測驗驗證,
大型分布式集成
1.可擴大 WorkerIdBitLength 到最大20,支持 1,048,576 個節點,且不影響上述并發性能(50W/0.1s),[演算法支持]
2.采用中心化 IdGenerator 集群,生成可用 Id 串列,存入 Redis 佇列供節點消費,此時64個中心化節點數足夠大型互聯網專案使用,[需集成方擴展實作]
3.以上2條二選一即可,采用方法2一般是因為不想增加最終 ID 長度,但節點數超過64個,
4.任何加大 WorkerIdBitLength 或 SeqBitLength 的設定,都可能會增加 ID 的長度,
配置變更
配置變更指是系統運行一段時間后,再變更運行引數(IdGeneratorOptions選項值),請注意:
1.最重要的一條原則是:BaseTime 只能往前(比老值更小、距離現在更遠)賦值,原因是往后賦值極大可能產生相同的時間戳,[不推薦在系統運行之后調整 BaseTime]
2.任何時候增加 WorkerIdBitLength 或 SeqBitLength,都是可以的,但是慎用 “減小”的操作,因為這可能導致在未來某天生成的 ID 與過去老配置時相同,[允許在系統運行之后增加任何一個 BitLength 值]
3.如果必須減小 WorkerIdBitLength 或 SeqBitLength 其中的一項,一定要滿足一個條件:新的兩個 BitLength 之和要大于 老的值之和,[不推薦在運行之后縮小任何一個 BitLength 值]
4.上述3條規則,并未在本演算法內做邏輯控制,集成方應根據上述規則做好影響評估,確認無誤后,再實施配置變更,
代碼示例
C#:查看示例
Java:查看示例
Go:查看示例
Rust:查看示例
即將推出 C 語言版本,
即將推出 PHP 擴展呼叫版本,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/270406.html
標籤:C#
