1. 程式人生 > >ID生成服務

ID生成服務

業務系統對ID的要求

  1. 全域性唯一性
  2. 趨勢遞增,保證有序
  3. 單調遞增,保證下一個ID一定大於上個ID,滿足排序等
  4. 無規則不規則,保證資訊保安,不能連續,防止扒取,比如訂單號可以計算單量
  5. 高可用性,一崩全崩
  6. 低延遲,高效能(QPS)

常見方法

UUID(Universally Unique Identifier)

標準型式包含32個16進位制數字,以連字號分為五段,形式為8-4-4-4-12的36個字元,示例:550e8400-e29b-41d4-a716-446655440000,到目前為止業界一共有5種方式生成UUID

  • 優點:效能高,本地生成,無網路消耗
  • 缺點
    • 不易於儲存:UUID太長
    • 不安全:基於MAC地址生成UUID的演算法可能會導致MAC地址洩露
    • ID作為主鍵時在特定的環境會存在一些問題,比如做DB主鍵的場景下,UUID就非常不適用。MYSQL官方建議主鍵越短越好

類snowflake方案

以劃分名稱空間來生成ID的一種演算法,這種方案把64-bit分別劃分成多段,分開來標示機器、時間 0 - 00000000 00000000 00000000 00000000 0 - 00000000 00 - 00000000 0000 41-bit的時間可以表示(1L<<41)/(1000L360024*365)=69年的時間,10-bit機器可以分別表示1024臺機器。如果我們對IDC劃分有需求,還可以將10-bit分5-bit給IDC,分5-bit給工作機器。這樣就可以表示32個IDC,每個IDC下可以有32臺機器,可以根據自身需求定義。12個自增序列號可以表示2^12個ID,理論上snowflake方案的QPS約為409.6w/s,這種分配方式可以保證在任何一個IDC的任何一臺機器在任意毫秒內生成的ID都是不同的

  • 優點
    • 毫秒在高位,自增序列在低位,ID趨勢遞增
    • 不依賴資料庫等第三方系統,以服務方式部署,穩定性高,效能也高
    • 可以根據自身業務分配bit位,靈活
  • 缺點
    • 強依賴機器時鐘,如果機器時鐘回撥,導致發號重複或服務不可用

資料庫生成

  • 優點

    • 非常簡單,利用現有資料庫系統的功能實現,成本小,有DBA專業維護。
    • ID號單調自增,可以實現一些對ID有特殊要求的業務。
  • 缺點

    • 強依賴DB,當DB異常時整個系統不可用,屬於致命問題。配置主從複製可以儘可能的增加可用性,但是資料一致性在特殊情況下難以保證。主從切換時的不一致可能會導致重複發號。
    • ID發號效能瓶頸限制在單臺MySQL讀寫效能

    對於MySQL效能問題,可用如下方案解決:在分散式系統中我們可以多部署幾臺機器,每臺機器設定不同的初始值,且步長和機器數相等。比如有兩臺機器。設定步長step為2,TicketServer1的初始值為1(1,3,5,7,9,11...)、TicketServer2的初始值為2(2,4,6,8,10...)。

    這種架構貌似能夠滿足效能的需求,但有以下幾個缺點:

    1. 系統水平擴充套件比較困難,比如定義好了步長和機器臺數之後,如果要新增機器該怎麼做
    2. ID沒有了單調遞增的特性,只能趨勢遞增,這個缺點對於一般業務需求不是很重要,可以容忍
    3. 資料庫壓力還是很大,每次獲取ID都得讀寫一次資料庫,只能靠堆機器來提高效能。

Leaf方案實現

Leaf-segment資料庫方案

    • 原方案每次獲取ID都得讀寫一次資料庫,造成資料庫壓力大。改為利用proxy server批量獲取,每次獲取一個segment(step決定大小)號段的值。用完之後再去資料庫獲取新的號段,可以大大的減輕資料庫的壓力。
    • 各個業務不同的發號需求用biz_tag欄位來區分,每個biz-tag的ID獲取相互隔離,互不影響。如果以後有效能需求需要對資料庫擴容,不需要上述描述的複雜的擴容操作,只需要對biz_tag分庫分表就行。
  • 資料庫表設計如下:
Field Type
biz_tag varchar(128)
max_id bigint(20)
step int(11)
desc varchar(256)
update_time timestamp

重要欄位說明:biz_tag用來區分業務,max_id表示該biz_tag目前所被分配的ID號段的最大值,step表示每次分配的號段長度。原來獲取ID每次都需要寫資料庫,現在只需要把step設定得足夠大,比如1000。那麼只有當1000個號被消耗完了之後才會去重新讀寫一次資料庫。讀寫資料庫的頻率從1減小到了1/step

  • 優點:
    • Leaf服務可以很方便的線性擴充套件,效能完全能夠支撐大多數業務場景。 ID號碼是趨勢遞增的8byte的64位數字,滿足上述資料庫儲存的主鍵要求。
    • 容災性高:Leaf服務內部有號段快取,即使DB宕機,短時間內Leaf仍能正常對外提供服務。
    • 可以自定義max_id的大小,非常方便業務從原有的ID方式上遷移過來。
  • 缺點:
    • ID號碼不夠隨機,能夠洩露發號數量的資訊,不太安全。
    • TP999資料波動大,當號段使用完之後還是會hang在更新資料庫的I/O上,tg999資料會出現偶爾的尖刺。
    • DB宕機會造成整個系統不可用。

原文 Leaf—美團點評分散式ID生成系統

同類文章:分散式ID生成器