開源乙個新的雪花演算法(雪花漂移)

2021-10-21 21:35:48 字數 4959 閱讀 2286

idgenerator

介紹用一種全新的雪花漂移演算法(以下簡稱本演算法),讓id更短、生成速度更快。

核心在於縮短id長度的同時,還能保持極高併發處理量(50w/0.1s),且具有很強配置能力。

需求**

1.作為架構設計的你,想要解決資料庫主鍵唯一的問題,特別是在分布式系統多資料庫的時候。

2.你希望這個主鍵是用最少的儲存空間,索引速度更快,select、insert 和 update 更迅速。

3.你要考慮在分庫分表(合庫合表)的時候,主鍵值可直接使用,並能反映業務時序。

4.如果這樣的主鍵值太長,超過前端 js number 型別最大值,須把 long 型轉換為 string 型,你會覺得有點沮喪。

5.哪怕 guid 能自增,但占用空間大,這也不是你想要的。

6.你希望系統能執行 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次漂移最大值)

效果1.js number 型別最大數值:9007199254740992,本演算法在保持併發效能(5w+/0.01s)和最大64個 workerid(6bit)的同時,能用70年才到 js number max 值。

2.增加workerid位數到8bit(128節點)時,15年達到 js number max 值。

3.極致效能:500w/1s。

4.所有測試資料均基於8代低壓i7計算。

「我」是什麼

1.本演算法是乙個類庫,它基於 net standard2.0 基礎庫,不依賴任何第三方元件。

2.本演算法不依賴任何外部資料系統(除了要被指定 workerid 之外)。

適用範圍

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.用單例模式呼叫。外部整合方使用更多的例項並行呼叫本演算法,不會增加id產出效能,因為本演算法採用單執行緒模式生成id。

2.指定唯一的 workerid。必須由外部系統確保 workerid 的全域性唯一性,並賦值給本演算法入口方法。

3.異常處理。本演算法內部會丟擲所有exception,外部系統 catch 相關資訊並做好應對處理,以免引發更大的系統崩潰。

4.認真理解 idgeneratoroptions 的定義,這對整合和使用本演算法有幫助。

5.訂閱id非同步通知。iidgenerator.genidactionasync 是乙個可以向外部系統非同步傳送id生成訊息的事件,它包含的消c#教程息型別有"漂移開始、漂移結束、時間回撥",具體參考 yitter.idgentest 的 program.cs 啟動**。不過訂閱id非同步通知會有細微的效能損失。

6.同步或同步呼叫。你可在外部系統的非同步(async標記)方法中呼叫本演算法,同步呼叫同樣沒問題。

7.使用雪花漂移演算法。雖然**裡包含了傳統雪花演算法的定義,並且你可以在入口處指定(method=2)來啟用傳統演算法,但仍建議你使用雪花漂移演算法(method=1,預設的),畢竟它具有更好的伸縮力和更高的效能。

8.輕易不要修改核心演算法。本演算法內部引數較多,邏輯較為複雜,在你尚未掌握核心邏輯時,請勿嘗試修改核心**且用於生產環境,除非通過大量細緻、科學的測試驗證。

大型分布式整合

1.可擴大 workeridbitlength 到最大20,支援 1,048,576 個節點,且不影響上述併發效能(50w/0.1s)。[演算法支援]

2.採用中心化 idgenerator 集群,給節點生成可用 id 列表,存入 redis 佇列供節點消費。此時64個中心化節點數足夠大型網際網路專案使用。[需整合方擴充套件實現]

3.以上2條二選一即可,採用方法2一般是因為不想增加最終 id 長度,但節點數超過64個。

4.任何加大 workeridbitlength 或 seqbitlength 的設定,都可能會增加 id 的長度。

配置變更

配置變更指是系統執行一段時間後,再變更執行引數(idgeneratoroptions選項值),請注意:

2.任何時候增加 workeridbitlength 或 seqbitlength,都是可以的,但是慎用 「減小」的操作,因為這可能導致在未來某天生成的 id 與過去老配置時相同。[允許在系統執行之後增加任何乙個 bitlength 值]

3.如果必須減小 workeridbitlength 或 seqbitlength 其中的一項,一定要滿足乙個條件:新的兩個 bitlength 之和要大於 老的值之和。[不推薦在執行之後縮小任何乙個 bitlength 值]

4.上述3條規則,並未在本演算法內做邏輯控制,整合方應根據上述規則做好影響評估,確認無誤後,再實施配置變更。

**示例

執行環境

1…net standard 2.0+

檔案說明

1.snowworkerm1.cs 是雪花漂移演算法。

2.snowworkerm2.cs 是傳統雪花演算法。

雪花漂移演算法

var options = new idgeneratoroptions()

;var newid = new yitidgenerator(options).newlong();

傳統雪花演算法

var options = new idgeneratoroptions()

;var newid = new yitidgenerator(options).newlong();

options說明

options引數(method、starttime除外)只支援漂移演算法,不支援傳統雪花演算法。

public class idgeneratoroptions

= 1;

/// /// 開始時間(utc格式)

/// 不能超過當前系統時間

///

public datetime starttime = datetime.minvalue;

/// /// 機器碼

/// 與 workeridbitlength 有關係

///

public ushort workerid = 0;

/// /// 機器碼位長

/// 範圍:2-21(要求:序列數字長+機器碼位長不超過22)。

/// 建議範圍:6-12。

///

public byte workeridbitlength = 6;

/// /// 序列數字長

/// 範圍:2-21(要求:序列數字長+機器碼位長不超過22)。

/// 建議範圍:6-14。

///

public byte seqbitlength = 6;

/// /// 最大序列數(含)

/// (由seqbitlength計算的最大值)

///

public int maxseqnumber = 0;

/// /// 最小序列數(含)

/// 預設11,不小於5,不大於maxseqnumber-2

///

public ushort minseqnumber = 11;

/// /// 最大漂移次數(含),

/// 預設2000,推薦範圍500-10000(與計算能力有關)

///

public int topovercostcount = 2000;

生成的id

預設配置:

workerid = 6 (最多64個工作節點)

seqbitlength = 6

id示例(基於預設配置):

129053495681099 (本演算法執行1年)

387750301904971 (執行3年)

646093214093387 (執行5年)

1292658282840139 (執行10年)

9007199254740992 (js number 最大值)

165399880288699493 (普通雪花演算法生成的id)

本演算法生成的 id 值,是 js number 最大值的 1%-10%,是普通雪花演算法值的千分之一,而計算能力卻超過普通雪花演算法。

如何通過雪花演算法用Python實現乙個簡單的發號器

實現乙個簡單的發號器 根據snowflake演算法的原理實現乙個簡單的發號器,產生不重複 自增的id。1.snowflake演算法的簡單描述 這裡的snowflake演算法是用二進位制的,有64位。其中41位的時間戳表示 當前時間戳減去某個設定的起始時間,10位標識表示 不同的機器 資料庫的標識id...

乙個分布式ID的生成器 雪花演算法

coding utf 8 create on 2020 11 23 author sandy import time class snowflake object def init self,datacenterid,machineid self.sequence 0 self.laststmp 1...

乙個新的開源bug管理系統Cynthia

下面是cynthia的主要介紹 cynthia 提供了乙個基於web的 開源的 跨平台的軟體專案管理和問題管理的解決方案。通過極大的靈活度,實現了特殊性和普遍性的統一。它提供了強大的自定義配置功能,使用者能夠根據自己的實際情況配置問題的流轉和資料模板,它同時內建了強大的cache模組提高資料的訪問效...