分佈式ID系列(2)——UUID適合做分佈式ID嗎

分佈式ID系列(2)——UUID適合做分佈式ID嗎

今天我們講一下使用UUID的方式來創建分佈式Id,看看UUID是否適合做分佈式ID的生成策略

UUID的生成策略:

UUID的方式能生成一串唯一隨機32位長度數據,它是無序的一串數據,按照開放軟件基金會(OSF)制定的標準計算,UUID的生成用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字。UUID的底層是由一組32位數的16進制數字構成,是故 UUID 理論上的總數為16的32次方,約等於

分佈式ID系列(2)——UUID適合做分佈式ID嗎

,也就是說若每納秒產生1百萬個 UUID,要花100億年才會將所有 UUID 用完(100億年啊,地球都沒了),所以這足夠我們的使用了,也能夠保證唯一性。

UUID的格式:

UUID 的十六個八位字節被表示為 32個十六進制數字,以連字號分隔的五組來顯示,形式為 8-4-4-4-12,總共有 36個字符(即三十二個英數字母和四個連字號)。例如:

123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

上面的以數字 M開頭的四位表示 UUID 版本,目前UUID的規範有5個版本,M可選值為1, 2, 3, 4, 5 ;各個版本的具體介紹如下所示:

version 1:0001。基於時間和 MAC 地址。由於使用了 MAC 地址,因此能夠確保唯一性,但是同時也暴露了 MAC 地址,私密性不夠好。

version 2:0010。DCE 安全的 UUID。該版本在規範中並沒有仔細說明,因此並沒有具體的實現。

version 3:0011。基於名字空間 (MD5)。用戶指定一個名字空間和一個字符串,通過 MD5 散列,生成 UUID。字符串本身需要是唯一的。

version 4:0100。基於隨機數。雖然是基於隨機數,但是重複的可能性可以忽略不計,因此該版本也是被經常使用的版本。

version 5:0101。基於名字空間 (SHA1)。跟 Version 3 類似,但是散列函數編程了 SHA1。

上面以數字 N開頭的四個位表示 UUID 變體( variant ),變體是為了能兼容過去的 UUID,以及應對未來的變化,目前已知的變體有如下幾種,因為目前正在使用的 UUID 都是 variant1,所以取值只能是 8,9,a,b 中的一個(分別對應1000,1001,1010,1011)。

variant 0:0xxx。為了向後兼容預留。

variant 1:10xx。當前正在使用的。

variant 2:11xx。為早期微軟 GUID 預留。variant 3:111x。為將來擴展預留。目前暫未使用。

Java實現UUID:

Java已經寫好一個UUID類供我們使用,如下所示

package one.util;
import java.util.UUID;
public class Test {
 public static void main(String[] args) {
 String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
 System.out.println("UUID的值是:" + uuid);
 }
}

結果如下所示

UUID的值是:24e6f66b3dfb4aba8e3e3801d3327e08

UUID是否適合做分佈式id:

如果需求是隻保證唯一性,那麼UUID也是可以使用的,但是按照上面的分佈式id的要求, UUID其實是不能做成分佈式id的,原因如下:

  • 首先分佈式id一般都會作為主鍵,但是安裝mysql官方推薦主鍵要儘量越短越好,UUID每一個都很長,所以不是很推薦
  • 既然分佈式id是主鍵,然後主鍵是包含索引的,然後mysql的索引是通過b+樹來實現的,每一次新的UUID數據的插入,為了查詢的優化,都會對索引底層的b+樹進行修改,因為UUID數據是無序的,所以每一次UUID數據的插入都會對主鍵地城的b+樹進行很大的修改,這一點很不好
  • 信息不安全:基於MAC地址生成UUID的算法可能會造成MAC地址洩露,這個漏洞曾被用於尋找梅麗莎病毒的製作者位置。

那麼UUID可以用到哪些方面呢

比如阿里雲每一條短信發送的唯一id,這個是可以的,比如從阿里雲官網截圖所示:

分佈式ID系列(2)——UUID適合做分佈式ID嗎


分享到:


相關文章: