分佈式ID
需求
- 全局唯一
- 高性能
- 高可用
- 簡單易用
UUID
優點:
- 唯一
- 不依賴於任何第三方服務
缺點:
- 是字符串類型而非數字,不滿足數字ID的需求
- 字符串太長了,DB查詢效率受影響
數據庫自增ID
如果使用 mysql 單實例:性能可能不夠;單實例的穩定性不強,宕機會影響業務
如何解決穩定性問題呢?
方案一:使用主從模式集群
存在的問題:滿足了高可用,但數據同步延時問題可能導致ID重複。
方案二:使用多主機主從模式集群,對多主機做高可用
必須設置自增起始值與步長
舉例:比如兩個主機 master1 只會產生奇數ID,master2 只會產生偶數ID
存在的問題:
- 性能依舊不足,每次都去請求數據庫
- 如果再新增一個主,擴展起來麻煩
如何解決性能問題呢?
方案三:使用號段模式,批量從數據庫獲取ID緩存起來,緩存中的ID一旦達到上限就再次去數據庫批量獲取
DB設計如下:
- biz_type 代表業務類型,業務隔離
- max_id 代表當前最大的可用 id
- step 代表號段的長度,合理設置即可
- version 是一個樂觀鎖,用來保證並發更新的正確性
最終方案
最終方案結合方案二和方案三的優點,DB設計如下:
- delta 表示緩存中的 ID 每次增量
- remainder 代表餘數
缺點:
- 擴展主機個數麻煩
- 實現複雜
雪花算法
- 使用一個 long 類型作為 ID
- 64位:第一位0表示正數 + 41位毫秒級時間戳 + 10位主機編號 + 12位序列號
- 時間戳通常是相對時間,這樣可用期限就更長,理論上支持 69 年
- 支持 1024-1=1023 個主機節點
- 支持同一個時間點同一台服務器生成 4096-1=4095 個序列號
主機編號手動分配太麻煩了,可以在 Zookeeper 中創建序列節點,用節點序號(緩存起來)作為主機編號。
優點:快
相關文章:
//www.liaoxuefeng.com/article/1280526512029729
//www.cnblogs.com/wuneng/p/11478160.html
//github.com/didi/tinyid/wiki/tinyid原理介紹
//mp.weixin.qq.com/s/hz7TntFDurwkAaSGODbF-Q