1. 程式人生 > >基於.NET Standard的分散式自增ID演算法--Snowflake

基於.NET Standard的分散式自增ID演算法--Snowflake

概述

本篇文章主要講述分散式ID生成演算法中最出名的Snowflake演算法。搞.NET開發的,資料庫主鍵最常見的就是int型別的自增主鍵和GUID型別的uniqueidentifier。
那麼為何還要引入snowflake呢?

INT自增主鍵

自增主鍵是解決主鍵生成的最簡單方案,它有如下優勢:

  1. 資料庫本身負責主鍵生成,效率高
  2. 資料庫本身保證主鍵順序遞增,方便儲存和檢索

相對應的,它也有如下缺點:

  1. 嚴重依賴資料庫服務
  2. 強順序遞增,不易橫向擴充套件
  3. 分庫分表很難處理
  4. 不方便匯入資料
  5. 上層應用在插入資料時,如果需要獲知主鍵,必須再次查詢

總結來說,INT自增主鍵在單機效能和主鍵嚴格遞增上由很大的優勢,但是在擴充套件性和分散式資料庫上有較大限制

GUID主鍵

GUID(全域性唯一識別符號,Globally Unique Identifier)為128位(16位元組),它使用太網絡卡地址、納秒級時間、晶片ID碼和許多可能的數字根據演算法動態生成,理論上可以有2^128個結果,
所以產生2個相同的ID的機率非常小。

它的優點如下:

  1. 應用生成,解放伺服器壓力
  2. 生成的ID可以做到全庫唯一,方便資料庫分庫分表、資料匯入

缺點也很明顯:

  1. 16位元組太長,浪費空間
  2. 非順序遞增,增加資料庫儲存和檢索開銷

在做資料庫主鍵選則時,如果系統較小,業務邏輯相對簡單,可以考慮使用自增主鍵;如果業務複雜,涉及到分庫分表分散式等,建議考慮GUID。如果認為GUID的缺點太影響使用,
可以考慮馬上開始重點介紹的分散式ID生成演算法 Snowflake

Snowflake是由Twitter提出並首先使用的分散式ID生成演算法,使用它來生成分散式趨勢遞增的Id。

  1. 分散式
    Id有分散式系統的節點自己生成

  2. 趨勢遞增
    主鍵非嚴格順序遞增的,而是根數時間順序遞增,這在一定程度上保證了資料儲存和索引的效率

演算法講解

總長度為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。

它的優點如下:

  1. 應用生成,解放伺服器壓力
  2. 生成的ID可以做到全庫唯一,方便資料庫分庫分表、資料匯入
  3. 8位元組,長整型,節省空間
  4. 趨勢遞增,方便資料儲存和查詢

如何在.NET中實現該演算法呢?下篇部落格重點揭曉。