【分布式ID】雪花、TDDL-SEQUENCE、UUID
分布式ID
要保證id不重復,主要從三方面考慮,時間維度、空間維度、原子維度;
時間維度:時間維度不重復,例如今天和明天不能重復,所以時間是可以加入id的一種因子;
空間維度:不同的機器,不同的環境生成的id不同,所以mac地址,機房地址等,都可以作為空間維度的區分;
原子維度:主要是線程的安全性,也就是遞增的保證,我們一般稱之為 序列 ,例如數據庫的自增id,就僅僅是原子維度;
討論完分布式id后,我們討論一下非功能性的一些要求:
高可用:可以隨時提供服務,不間斷;
低延遲:id獲取速度要快;
高并發:支持高QPS;
雪花算法
雪花算法生成的ID是一個64 bit的long型的數字且按時間趨勢遞增。大致由首位無效符(0,1bit)、時間戳差值(41bit)、機器編碼(10bit),序列號四部分組成(12bit)。
- 雪花算法是可以保證一定程度上的遞增
- 雪花算法基于高并發下,時間的最小精度可以生產最多的序列號個數決定了不重復率
UUID
- 基本自帶實現,同樣考慮:時間、空間、序列號維度,有多個實現版本。
- 無序,長度太大,對數據庫不友好。
TDDL
分布式序列:阿里內部的較多用法,主要是解決一個序列原子性的問題,首先它的序列是維護在數據中的,用一張表表示,每次獲取一定個數(如10000)的序列到進程中使用。
為了保證高可用,和高并發,維護序列的必然不能只是一張表,所以可以搞n張表,每一個數據庫表,維護一個sequence,所以就有了單個步長和組步長的說法。
序列的獲取如下所示:
時間維度:既然用了序列,因為序列的位數是有限的,那么必然就會重復,所以同樣的,在同一個時刻內,一個序列不能做了一次重復,但一般如果時間精確到某一個維度,現實的重復可能性基本為0。但不管如何,時間維度是必須要加的
- 遞增,做數據庫主鍵比較合適
- 高可用,不會單機崩潰出現問題
- 由于獲取sequence是一次性獲取多個在進場內部使用的,所以很有可能會造成空洞問題
純序列
Redis:集群高可用,但是部署復雜,維護難;可讀性好,容易記住,存儲占有空間少。
SQL自增:實現簡單,但是性能不高;可讀性好,容易記住,存儲占有空間少。
--------------------------------
優秀、是一種習慣
、、、、、、、、、、、、、、、

浙公網安備 33010602011771號