分布式ID生成器解決方案

2021-09-11 03:24:12 字數 2159 閱讀 1580

github:

大資料成神之路~預計更新500+篇文章,已經更新50+篇~

本文主要介紹在乙個分布式系統中, 怎麼樣生成全域性唯一的 id

在分布式系統存在多個 shard 的場景中, 同時在各個 shard 插入資料時, 怎麼給這些資料生成全域性的 unique id?

在單機系統中 (例如乙個 mysql 例項), unique id 的生成是非常簡單的, 直接利用 mysql 自帶的自增 id 功能就可以實現.

但在乙個存在多個 shards 的分布式系統 (例如多個 mysql 例項組成乙個集群, 在這個集群中插入資料), 這個問題會變得複雜, 所生成的全域性的 unique id 要滿足以下需求:

如果沒有上面這些限制, 問題會相對簡單, 例如:

在要滿足前面 6 點要求的場景中, 怎麼來生成全域性 unique id 呢?

twitter 的 snowflake 是一種比較好的做法. 下面主要介紹 twitter snowflake, 以及它的變種

snowflake 生成的 unique id 的組成 (由高位到低位):

一共 63 bits (最高位是 0)

unique id 生成過程:

異常情況討論:

從這個異常情況可以看出, 如果 snowflake 所執行的那些機器時鐘有大的偏差時, 整個 snowflake 系統不能正常工作 (偏差得越多, 分配新 id 時等待的時間越久)

從 snowflake 的官方文件 (/#system-clock-dependency) 中也可以看到, 它明確要求 「you should use ntp to keep your system clock accurate」. 而且最好把 ntp 配置成不會向後調整的模式. 也就是說, ntp 糾正時間時, 不會向後回撥機器時鐘.

snowflake 有一些變種, 各個應用結合自己的實際場景對 snowflake 做了一些改動. 這裡主要介紹 3 種.

變化:id 長度擴充套件到 128 bits:

最高 64 bits 時間戳;

然後是 48 bits 的 worker 號 (和 mac 位址一樣長);

最後是 16 bits 的 seq number

由於它用 48 bits 作為 worker id, 和 mac 位址的長度一樣, 這樣啟動時不需要和 zookeeper 通訊獲取 worker id. 做到了完全的去中心化

基於 erlang

它這樣做的目的是用更多的 bits 實現更小的衝突概率, 這樣就支援更多的 worker 同時工作. 同時, 每毫秒能分配出更多的 id

******flake 的思路是取消 worker 號, 保留 41 bits 的 timestamp, 同時把 sequence number 擴充套件到 22 bits;

******flake 的特點:

sequence number 完全靠隨機產生 (這樣也導致了生成的 id 可能出現重複)

沒有 worker 號, 也就不需要和 zookeeper 通訊, 實現了完全去中心化

timestamp 保持和 snowflake 一致, 今後可以無縫公升級到 snowflake

******flake 的問題就是 sequence number 完全隨機生成, 會導致生成的 id 重複的可能. 這個生成 id 重複的概率隨著每秒生成的 id 數的增長而增長.

所以, ******flake 的限制就是每秒生成的 id 不能太多 (最好小於 100次/秒, 如果大於 100次/秒的場景, ******flake 就不適用了, 建議切換回 snowflake).

先簡單介紹一下 instagram 的分布式儲存方案:

instagram unique id 的組成:

生成 unique id 時, 41 bits 的 timestamp 和 snowflake 類似, 這裡就不細說了.

主要介紹一下 13 bits 的 logic shard 代號 和 10 bits 的 sequence number 怎麼生成.

logic shard 代號:

sequence number 利用 postgresql 每個 table 上的 auto-increment sequence 來生成:

instagram 這個方案的優勢在於:

同時, 今後做資料遷移的時候, 也是按 logic shard 為單位做資料遷移的, 所以這種做法也不會影響到今後的資料遷移

分布式ID生成器的解決方案總結

在網際網路的業務系統中,涉及到各種各樣的id,如在支付系統中就會有支付id 退款id等。那一般生成id都有哪些解決方案呢?特別是在複雜的分布式系統業務場景中,我們應該採用哪種適合自己的解決方案是十分重要的。下面我們一一來列舉一下,不一定全部適合,這些解決方案僅供你參考,或許對你有用。乙個id一般來說...

分布式ID生成器

一 需求緣起 幾乎所有的業務系統,都有生成乙個唯一記錄標識的需求,例如 這個記錄標識往往就是資料庫中的主鍵,資料庫上會建立聚集索引 cluster index 即在物理儲存上以這個字段排序。這個記錄標識上的查詢,往往又有分頁或者排序的業務需求,例如 所以往往要有乙個time欄位,並且在time欄位上...

分布式 ID 生成器

乙個唯一 id 在乙個分布式系統中是非常重要的乙個業務屬性,其中包括一些如訂單 id,訊息 id 會話 id,他們都有一些共有的特性 全域性唯一很好理解,目的就是唯一標識某個次請求,某個業務。通常有以下幾種方案 可以利用mysql中的自增屬性auto increment來生成全域性唯一 id,也能保...