概述
本篇文章主要講述分佈式ID生成算法中最出名的Snowflake算法。搞開發的,數據庫主鍵最常見的就是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字節,長整型,節省空間
- 趨勢遞增,方便數據存儲和查詢
閱讀更多 程序員yrf 的文章