九種主流的分佈式 ID 生成策略
前言
構建分佈式系統時,如何對數據進行唯一標識也是一個至關重要的設計。不僅要符合 B-tree 數據結構以維持查詢性能,還要考慮唯一標識的連續性會不會影響系統安全性。在分庫分表的情況下,還要避免唯一標識重複且高效等等需要考慮的點。
爲此,市場就出現了很多分佈式 ID 生成方案。本文將詳細介紹九種主流的分佈式 ID 生成策略供大家參考使用。
1、UUID
UUID(Universally Unique Identifier) 是基於當前時間、計數器和硬件標識(通常爲無線網卡的 MAC 地址)等數據計算生成的。
示例代碼
JDK 提供了 UUID 生成工具,示例代碼如下:
存在的問題
UUID 完全可以滿足分佈式唯一標識,但是在實際應用過程中一般不採用,有幾個原因:
-
存儲成本高:UUID 太長,16 字節 128 位,以 36 長度的字符串表示,很多場景不適用。
-
信息不安全:基於 MAC 地址生成的 UUID 算法會暴露 MAC 地址,曾經梅麗莎病毒的製造者就是根據 UUID 尋找的。
-
不符合 MySQL 主鍵要求:MySQL 官方有明確的建議,主鍵要儘量越短越好,因爲太長對 MySQL 索引不利。
(如果 UUID 作爲數據庫主鍵,在 InnoDB 引擎下,UUID 的無序性可能會引起數據位置頻繁變動,嚴重影響性能。)
2、數據庫自增 ID
利用 MySQL 自增的 ID,可以達到數據唯一標識。
但是分庫分表後不能保證整體的 ID 唯一。爲了避免這種情況,有以下兩種方式可以解決該問題。
全局主鍵表
創建全局主鍵表維護唯一標識,作爲 ID 的輸出源可以保證整體 ID 的唯一。
主鍵表示例:
當業務獲取唯一標識時,執行下方 SQL 獲取,然後添加到某個分表中。
ID 自增步長設置
通過設置 MySQL 主鍵自增步長,讓分佈在不同實例的表數據 ID 做到不重複,從而保證整體的唯一。
如下,可以設置實例 1 步長爲 1,實例 1 步長爲 2。
顯然,這種方式的擴展性會是一個非常大的問題。
3、號段模式
號段模式介紹
號段模式是當下分佈式 ID 生成器的主流實現方式之一。其原理如下:
-
號段模式每次從數據庫取出一個號段範圍,加載到服務內存中。避免每次生成 ID 都去訪問數據庫。
-
當號段 ID 用完,再次向數據庫申請新號段,對 max_id 字段做一次 update 操作,新的號段範圍是 (max_id ,max_id +step]。
-
由於多業務端可能同時操作,所以採用版本號 version 樂觀鎖方式更新。
表結構如下:
優缺點
這種分佈式 ID 生成方式不強依賴於數據庫,不會頻繁的訪問數據庫,對數據庫的壓力小很多。
但同樣也會存在一些缺點,比如:服務器重啓,單點故障會造成 ID 不連續。
4、Redis INCR
作爲共享內存,可以通過 Redis 的 INCR 命令來生成全局唯一 ID。
簡單的代碼示例
Redis 也有對應的缺點:ID 生成的持久化問題,如果 Redis 宕機了怎麼進行恢復是開發人員需要考慮的。
5、雪花算法
Snowflake,雪花算法是有 Twitter 開源的分佈式 ID 生成算法,以劃分命名空間的方式將 64bit 位分割成了多個部分,每個部分都有具體的不同含義,在 Java 中 64Bit 位的整數是 Long 類型,所以在 Java 中 Snowflake 算法生成的 ID 就是 long 來存儲的。具體如下:
雪花算法強依賴機器時鐘,如果機器上時鐘回撥,會導致重複。通常通過記錄最後使用時間處理該問題。
6、美團 (Leaf)
美團點評分佈式 ID 生成系統。支持號段模式和 snowflake 算法模式,可以切換使用。
開源項目鏈接:
https://github.com/Meituan-Dianping/Leaf
Leaf 詳細介紹:
https://tech.meituan.com/2017/04/21/mt-leaf.html
7、百度 (Uidgenerator)
UidGenerator 是百度開源的 Java 語言實現,基於 Snowflake 算法的。克服了雪花算法的併發限制,單個實例的 QPS 能超過 6000000。需要的環境:JDK8+,MySQL(用於分配 WorkerId)。
源碼地址:
https://github.com/baidu/uid-generator
中文文檔地址:
https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md
8、滴滴 (TinyID)
Tinyid 是滴滴基於美團(Leaf)的號段模式基礎上升級而來,不僅支持了數據庫多主節點模式,還提供了 tinyid-client 客戶端的接入方式,使用起來更加方便。
開源項目鏈接:
https://github.com/didi/tinyid
總結比較
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Q4-oXXGUMJrxX5EEV2F77w