分散式唯一ID的生成方案

  • 2019 年 12 月 15 日
  • 筆記

分散式ID的特性

  • 全局唯一

不能出現重複的ID,這是最基本的要求。

  • 遞增

有利於關係資料庫索引性能。

  • 高可用

既然是服務於分散式系統,為多個服務提供ID服務,訪問壓力一定很大,所以需要保證高可用。

  • 資訊安全

如果ID是有規律的,就容易被惡意操作,在一些場景下需要ID無規則。

生成方案

UUID

核心思想是結合機器的網卡、當地時間、一個隨機數來生成。

優點:

  • 性能非常高,本地生成,沒有網路消耗。
  • 生成簡單,沒有高可用風險。
  • 有利於資訊安全,因為可讀性差,無規律。

缺點:

  • 太長,不易於存儲。
  • 有利於資訊安全的同時,也有不安全性,因為基於MAC地址生成的演算法可能會泄露MAC地址。
  • 無序,對MySQL索引不利,在 InnoDB 中,無序性會導致數據位置頻繁變動,性能低下。

資料庫

利用資料庫自增ID的特性來生成,如 MySQL 的 auto_increment

優點:

  • 簡單,利用資料庫自有功能實現。
  • 絕對有序。

缺點:

  • 有重複發號的風險,例如資料庫主從切換的場景。
  • 需要特別保障其高可用。
  • 發號性能限制於資料庫性能,如需提高發號能力,需要擴充資料庫,成本高。

Redis

Redis 提供了自增的原子命令,可以保證唯一、有序。

優點:

  • 簡單,自有能力。
  • 高並發環境下性能好,優於資料庫。
  • 維護成本低於資料庫。

缺點:

  • 主從切換時也可能會重複發號。
  • 需要特別保障其高可用。

雪花演算法

給每台機器分配一個唯一標識,然後通過下面的結構實現全局唯一ID:

時間戳 + 機器標識 + 自增序列號

毫秒在高位,自增序列在低位,一定是遞增的。

優點:

  • 生成性能高。
  • 靈活,可以根據自身業務特點分配bit位。

缺點:

  • 強依賴機器時鐘,如果時鐘回撥,就會導致服務異常。

小結

不同的方案有不同的特點,需要根據自己的需求場景來選擇適合的。

例如在美團早期,ID方案就是多種形式的:

  • 有的業務通過 DB 自增的方式生成
  • 有的業務通過 Redis 快取來生成
  • 有的業務直接用 UUID 生成

後來推出了一個類雪花演算法的分散式ID服務:Leaf,QPS壓測結果近5w/s。

項目地址:

https://github.com/Meituan-Dianping/Leaf

再推薦2個參考項目:

  • 基於 Redis 的生成器

https://github.com/hengyunabc/redis-id-generator

  • 百度基於雪花演算法的生成器

https://github.com/baidu/uid-generator