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

2022-09-07 16:00:15 字數 1534 閱讀 7792

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

乙個id一般來說有下面幾種要素:

系統時間毫秒數

我們可以使用當前系統時間精確到毫秒數+業務屬性+使用者屬性+隨機數+…等引數組合形式來確保id的唯一性,缺點是id的有序性難以保證,要保證有序性就要依賴資料庫或者其他中間儲存媒介。

uuid

j**a自帶的生成uuid的方式就能生成一串唯一隨機32位長度資料,而且夠我們用n億年,保證唯一性肯定是不用說的了,但缺點是它不包含時間、業務資料可讀性太差了,而且也不能id的有序遞增。

這是一種簡單的生成方式,簡單,高效,但在一般業務系統中我還沒見過有這種生成方式。

資料庫自增id

我們都知道為資料庫主鍵設定自增序號,以一定的趨勢自增,以保證主鍵id的唯一性。

這個方案很簡單,但最主要的問題在於依賴資料庫本身,這就無形增加了對資料庫的訪問壓力和依賴,一旦對單庫進行分庫分表或者資料遷移就尷尬了。

所以,這也不是合適的id生成方法。

批量生成id

一次按需批量生成多個id,每次生成都需要訪問資料庫,將資料庫修改為最大的id值,並在記憶體中記錄當前值及最大值。這樣就避免了每次生成id都要訪問資料庫並帶來壓力。

這種方案服務就是單點了,如果服務重啟勢必會造成id丟失不連續的情況,而且這種方式也不利於水平擴充套件。

中介軟體redis的所有命令操作都是單執行緒的,本身提供像incr這樣的自增命令,所以能保證生成的id肯定是唯一有序的。

這種方式不依賴關聯式資料庫,而且速度快。但系統要引入redis這一中介軟體,增加維護成本,而且編碼和配置工作量比較大。即使已經有了redis元件,但生成id的高頻率訪問對單執行緒的redis效能勢必也會造成影響。

還可以利用像zookeeper中的znode資料版本來生成序列號,及mongodb的objectid等,這種利用中介軟體的做法不是很推薦。

snowflake演算法

如上圖的所示,twitter的snowflake演算法下面幾部分組成:

這種方案效能好,在單機上是遞增的,但是由於涉及到分布式環境,每台機器上的時鐘不可能完全同步,也許有時候也會出現不是全域性遞增的情況。

而且這個專案在2010就停止維護了,但這個設計思路還是應用於其他各個id生成器及變種。

uidgenerator

leaf

leaf是美團開源的分布式id生成器,能保證全域性唯一性、趨勢遞增、單調遞增、資訊保安,裡面也提到了幾種分布式方案的對比,但也需要依賴關聯式資料庫、zookeeper等中介軟體。

推薦閱讀面經:史上最全j**a多執行緒面試題及答案

分布式ID生成器解決方案

github 大資料成神之路 預計更新500 篇文章,已經更新50 篇 本文主要介紹在乙個分布式系統中,怎麼樣生成全域性唯一的 id 在分布式系統存在多個 shard 的場景中,同時在各個 shard 插入資料時,怎麼給這些資料生成全域性的 unique id?在單機系統中 例如乙個 mysql 例...

分布式ID生成器

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

分布式 ID 生成器

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