基於.NET Standard的分散式自增ID演算法--Snowflake
概述
本篇文章主要講述分散式ID生成
演算法中最出名的Snowflake
演算法。搞.NET開發的,資料庫主鍵最常見的就是int型別的自增主鍵和GUID型別的uniqueidentifier。
那麼為何還要引入snowflake呢?
INT自增主鍵
自增主鍵是解決主鍵生成的最簡單方案,它有如下優勢:
- 資料庫本身負責主鍵生成,效率高
- 資料庫本身保證主鍵順序遞增,方便儲存和檢索
相對應的,它也有如下缺點:
- 嚴重依賴資料庫服務
- 強順序遞增,不易橫向擴充套件
- 分庫分表很難處理
- 不方便匯入資料
- 上層應用在插入資料時,如果需要獲知主鍵,必須再次查詢
總結來說,INT自增主鍵在單機效能和主鍵嚴格遞增上由很大的優勢,但是在擴充套件性和分散式資料庫上有較大限制
GUID主鍵
GUID(全域性唯一識別符號,Globally Unique Identifier)為128位(16位元組),它使用太網絡卡地址、納秒級時間、晶片ID碼和許多可能的數字根據演算法動態生成,理論上可以有2^128個結果,
所以產生2個相同的ID的機率非常小。
它的優點如下:
- 應用生成,解放伺服器壓力
- 生成的ID可以做到全庫唯一,方便資料庫分庫分表、資料匯入
缺點也很明顯:
- 16位元組太長,浪費空間
- 非順序遞增,增加資料庫儲存和檢索開銷
在做資料庫主鍵選則時,如果系統較小,業務邏輯相對簡單,可以考慮使用自增主鍵;如果業務複雜,涉及到分庫分表分散式等,建議考慮GUID。如果認為GUID的缺點太影響使用,
可以考慮馬上開始重點介紹的分散式ID生成演算法 Snowflake
Snowflake是由Twitter提出並首先使用的分散式ID生成演算法,使用它來生成分散式趨勢遞增的Id。
分散式
Id有分散式系統的節點自己生成趨勢遞增
主鍵非嚴格順序遞增的,而是根數時間順序遞增,這在一定程度上保證了資料儲存和索引的效率
演算法講解
總長度為64位長整型(8位元組)
1位:首位元組固定為0,來保證所有生成的資料都是正數
41位:第2到第42位工41位元組,用於生成毫秒級時間戳,計算大概(2^41−1)/(1000∗60∗60∗24∗365)=69 年,對於一般系統來說絕對夠用。
10位: 第43位到第52位為工作機ID,可表示2^10=1024臺裝置,一般高5位表示機房Id(datacenterId),低5位表示工作節點ID(workid)
12位:第53位到第64位表示序列號,2^12-1=4095
綜上演算法,表示單機每毫秒可以提供4095個Id,所有機器每毫秒可生成4095*1024=4194304個Id。
它的優點如下:
- 應用生成,解放伺服器壓力
- 生成的ID可以做到全庫唯一,方便資料庫分庫分表、資料匯入
- 8位元組,長整型,節省空間
- 趨勢遞增,方便資料儲存和查詢
如何在.NET中實現該演算法呢?下篇部落格重點揭曉。