分布式系統全域性唯一ID簡介 特點 生成

2021-09-19 23:26:50 字數 1992 閱讀 7885

在複雜分布式系統中,往往需要對大量的資料和訊息進行唯一標識。

如在金融、電商、支付、等產品的系統中,資料日漸增長,對資料分庫分表後需要有乙個唯一id來標識一條資料或訊息,資料庫的自增id顯然不能滿足需求,此時乙個能夠生成全域性唯一id的系統是非常必要的。

全域性唯一性:不能出現重複的id號,既然是唯一標識,這是最基本的要求。

趨勢遞增:在mysql innodb引擎中使用的是聚集索引,由於多數rdbms使用b-tree的資料結構來儲存索引資料,在主鍵的選擇上面我們應該盡量使用有序的主鍵保證寫入效能。

同時除了對id號碼自身的要求,業務還對id號生成系統的可用性要求極高,想象一下,如果id生成系統癱瘓,這就會帶來一場災難。

平均延遲和tp999延遲都要盡可能低;

可用性5個9;

高qps。

uuid(universally unique identifier)的標準型式包含32個16進製制數字,以連字型大小分為五段,形式為8-4-4-4-12的36個字元,示例:550e8400-e29b-41d4-a716-446655440000,到目前為止業界一共有5種方式生成uuid,詳情見ietf發布的uuid規範 a universally unique identifier (uuid) urn namespace。

優點:

缺點:以mysql舉例,利用給字段設定auto_increment_increment和auto_increment_offset來保證id自增,每次業務使用下列sql讀寫mysql得到id號。

這種方案的優缺點如下:

優點:

缺點:當使用資料庫來生成id效能不夠要求的時候,我們可以嘗試使用redis來生成id。

這主要依賴於redis是單執行緒的,所以也可以用生成全域性唯一的id。可以用redis的原子操作 incr和incrby來實現。

比較適合使用redis來生成每天從0開始的流水號。比如訂單號=日期+當日自增長號。可以每天在redis中生成乙個key,使用incr進行累加。

優點:1)不依賴於資料庫,靈活方便,且效能優於資料庫。

2)數字id天然排序,對分頁或者需要排序的結果很有幫助。

缺點:1)如果系統中沒有redis,還需要引入新的元件,增加系統複雜度。

2)需要編碼和配置的工作量比較大。

zookeeper主要通過其znode資料版本來生成序列號,可以生成32位和64位的資料版本號,客戶端可以使用這個版本號來作為唯一的序列號。

很少會使用zookeeper來生成唯一id。主要是由於需要依賴zookeeper,並且是多步調用api,如果在競爭較大的情況下,需要考慮使用分布式鎖。因此,效能在高併發的分布式環境下,也不甚理想。

這種方案大致來說是一種以劃分命名空間(uuid也算,由於比較常見,所以單獨分析)來生成id的一種演算法,這種方案把64-bit分別劃分成多段,分開來標示機器、時間等,比如在snowflake中的64-bit分別表示如下圖(來自網路)所示:

41-bit的時間可以表示(1l<<41)/(1000l360024*365)=69年的時間,10-bit機器可以分別表示1024臺機器。如果我們對idc劃分有需求,還可以將10-bit分5-bit給idc,分5-bit給工作機器。這樣就可以表示32個idc,每個idc下可以有32臺機器,可以根據自身需求定義。12個自增序列號可以表示2^12個id,理論上snowflake方案的qps約為409.6w/s,這種分配方式可以保證在任何乙個idc的任何一台機器在任意毫秒內生成的id都是不同的。

這種方式的優缺點是:

優點:

缺點:

應用舉例mongdb objectid

mongodb官方文件 objectid可以算作是和snowflake類似方法,通過「時間+機器碼+pid+inc」共12個位元組,通過4+3+2+3的方式最終標識成乙個24長度的十六進製制字元。

分布式系統全域性唯一ID

全域性的唯一流水id 可以將乙個請求在分布式系統中的流轉路徑聚合。生成唯一id有兩種方法 持久型 使用資料庫表自增欄位或者sequence 生成,為了提高效率,每個應用節點可以快取乙個批次的id 如果機器重啟則可能會損失一部分id 但是這並不會產生任何問題。時間型 一般由機器號 業務號 時間 單節點...

分布式系統全域性唯一ID生成

在複雜分布式系統中,往往需要對大量的資料和訊息進行唯一標識。如在金融 電商 支付 等產品的系統中,資料日漸增長,對資料分庫分表後需要有乙個唯一id來標識一條資料或訊息,資料庫的自增id顯然不能滿足需求,此時乙個能夠生成全域性唯一id的系統是非常必要的。同時除了對id號碼自身的要求,業務還對id號生成...

分布式全域性唯一ID(二)

redis 實現分布式唯一id,其實這個也很簡單,主要使用redis string資料結構的 increment 方法。原理 使用increment方法,每次自加1,主要使用redis的高效能和單執行緒。實現方式 核心 如下,若是為了保證長度一致,其實可以預先初始化值。現在的這個是從1,2.逐漸遞增...