分佈式ID

需求

  • 全局唯一
  • 高性能
  • 高可用
  • 簡單易用

UUID

優點:

  • 唯一
  • 不依賴於任何第三方服務

缺點:

  • 是字符串類型而非數字,不滿足數字ID的需求
  • 字符串太長了,DB查詢效率受影響

數據庫自增ID

如果使用 mysql 單實例:性能可能不夠;單實例的穩定性不強,宕機會影響業務

如何解決穩定性問題呢?

方案一:使用主從模式集群

存在的問題:滿足了高可用,但數據同步延時問題可能導致ID重複。

方案二:使用多主機主從模式集群,對多主機做高可用

必須設置自增起始值與步長
舉例:比如兩個主機 master1 只會產生奇數ID,master2 只會產生偶數ID

存在的問題:

  • 性能依舊不足,每次都去請求數據庫
  • 如果再新增一個主,擴展起來麻煩

如何解決性能問題呢?

方案三:使用號段模式,批量從數據庫獲取ID緩存起來,緩存中的ID一旦達到上限就再次去數據庫批量獲取

DB設計如下:
image

  • biz_type 代表業務類型,業務隔離
  • max_id 代表當前最大的可用 id
  • step 代表號段的長度,合理設置即可
  • version 是一個樂觀鎖,用來保證並發更新的正確性

最終方案

最終方案結合方案二和方案三的優點,DB設計如下:
image

  • 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

Tags: