分散式唯一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