作者:錢江奇 李鳴揚
單位:中國移動智慧家庭運營中心?智慧互聯(lián)產(chǎn)品部
Labs 導(dǎo)讀
UUID是國際標準化組織(ISO)提出的一個概念。UUID用來識別屬性類型,在所有空間和時間上被視為唯一的標識。本文將從UUID的構(gòu)成方式、現(xiàn)行版本、生成策略、應(yīng)用案例等方面作介紹。
Part 01●??什么是UUID?●
UUID全稱Universal Unique Identifier是一串128位數(shù)字碼,用于唯一識別網(wǎng)絡(luò)對象或者事件。由于其獨特的生成機制和使用場景,UUID可以確保全局唯一性,避免重復(fù)。UUID廣泛應(yīng)用于各種需要唯一識別的場景,例如數(shù)據(jù)庫主鍵、系統(tǒng)實例ID, 識別生命周期短暫的藍牙配置文件和對象等。
UUID是類似于GUID的術(shù)語,最初由微軟引入的GUID實際上是UUID的一種變體,在RFC 4122規(guī)范中將這兩個術(shù)語定義為同義詞。隨后,開放軟件基金會(OSF)對UUID進行了標準化,使其成為分布式計算網(wǎng)絡(luò)中的重要組成部分,衍生出的各個UUID版本都遵循RFC 4122規(guī)范。
Part 02●??UUID的構(gòu)成方式?●
但如果計UUID通常通過特定算法生成,例如基于時間戳或網(wǎng)絡(luò)地址等。UUID通過特定的組合排列方式確保其唯一性,由32個16進制數(shù)字(包括數(shù)字0到9和字母A到F)和4個連字符構(gòu)成。每個連字符的字符數(shù)是8-4-4-4-12,其中最后4位或者N位表示格式和編碼:
UUID也可以用十進制或者二進制格式表示:
傳統(tǒng)的UUID大致分成3種變體:
? 變體0:為了兼容80年代未過時的阿波羅網(wǎng)絡(luò)計算系統(tǒng)而保留,它的結(jié)構(gòu)與目前使用的version 1相似。
? 變體1:目前主要使用的變體,在Internet工程文檔規(guī)范中被定義為RFC 4122/DCE 1.1 UUID或Leach-Salz UUID,例如微軟的GUID就是UUID的變體1。
? 變體2:為了兼容微軟后續(xù)發(fā)展而保留,盡管現(xiàn)有的微軟GUID是UUID的變體1,但早期Windows平臺使用的是變體2。變體1和變體2在N位位置的比特數(shù)字不同,例如變體1使用2位比特位,而變體2使用3位比特位。
Part 03●??UUID的現(xiàn)行版本?●
現(xiàn)有的UUID主要是基于變體1衍生出來的,由5個不同版本組成,不同版本的UUID生成方式有所區(qū)別,具體包括:
? Version1:基于時間戳和節(jié)點生成的UUID。它使用當(dāng)前時間和計算機的MAC地址來生成唯一標識符。這個版本的UUID保證了全局唯一性和時間排序性,但在某些情況下可能存在安全性和隱私問題。
? Version2:基于DCE安全標識符(DCE Security Identifier)生成的UUID。這個版本的UUID將標識符的角色和權(quán)限信息編碼到UUID中,使其能夠表示用戶、組和ACL(訪問控制列表)。然而,這個版本的UUID并不常見,也沒有得到廣泛支持。
? Version3:基于名稱和命名空間生成的UUID。它使用MD5散列函數(shù)對名稱和命名空間進行處理,生成唯一的標識符。這個版本的UUID可用于標識命名空間中的對象,如URL、域名等。
? Version4:基于隨機數(shù)生成的UUID。這個版本的UUID使用隨機數(shù)生成算法生成,因此具有很高的隨機性和唯一性。它是目前最常用的UUID版本,廣泛應(yīng)用于各種領(lǐng)域。
? Version5:基于名稱和命名空間生成的UUID。它與Version 3相似,但使用的是SHA-1散列函數(shù),提供更強的散列算法。這個版本的UUID也可用于標識命名空間中的對象。
Part 04●??現(xiàn)有UID的生成策略?●
4.1 Mysql生成ID
Mysql使用主鍵auto_increment方式生成ID,ID之間的步長固定,但可以自定義步長。這種方式簡單易用,可以保證ID的遞增性和唯一性,但是存在單點故障和數(shù)據(jù)一致性問題、在擴展性方面也存在一定的挑戰(zhàn)。
4.2 MongoDB生成ID
MongoDB生成的UUID是由12字節(jié)十六進制數(shù)字組成,具體組成:4字節(jié)--以秒為單位的時間戳,3字節(jié)--機器標識符,2字節(jié)--進程ID,3字節(jié)--計數(shù)器(從一個隨機值開始)。比傳統(tǒng)的UUID短,但比MYSQL自動增量字段(64位Bigint值)長。
4.3 Redis生成ID
Redis通常使用原子操作INCR或INCRBY實現(xiàn)ID生成。如果是Redis集群可以設(shè)置ID初始值并自定義每個節(jié)點ID的步長。由于Redis是單線程模型,可以保證生成的ID具備唯一性。
4.4 Zookeeper生成ID
Zookeeper主要通過ZNODE數(shù)據(jù)版本生成ID,此ID通常是32位或者64位字符串構(gòu)成,客戶端可以使用該ID作為UID使用。由于需要強依賴Zookeeper,在高并發(fā)的場景多的情況下很少考慮使用這種方式。
Part 05●??UUID的應(yīng)用案例分析?●
5.1 Twitter生成UUID
Twitter使用雪花算法作為專業(yè)服務(wù)來統(tǒng)一生成64位唯一標識符,用于分布式系統(tǒng)中的對象標識,例如推特、直接消息、列表等。這些ID是基于時間的的唯一無符號64位整數(shù),完整的ID定義主要組成方式如下:
41位--時間戳以毫秒為單位(相對于任何自定義紀元,通常可以使用69年)
10位--已配置的機器/節(jié)點/分片ID
12位--序列號(每臺機器的本地計算器,每4096個值后設(shè)置為0)
1位--額外保留位,一般被設(shè)置為0來確??倲?shù)為正值
按著這種方法構(gòu)成的UID不僅提高可用性,因為使用時間戳為首部分,還可以根據(jù)時間進行排序。默認情況下,雪花算法生成一個64位的無符號長整型,也就是長度為19的ID。有時具體項目中可能不需要這么長,也可以根據(jù)自身需要修改該算法。
5.2 百度生成UUID
百度基于雪花算法改進生成UID,對UID的bit位進行調(diào)整,將時間戳部分修改為28位,用于表示當(dāng)前時間與初始上線生成的時間的時間差(單位為秒),其中初始時間可以手工配置。使用22位表示工作節(jié)點ID,實例啟動的時候生成分布式ID,寫入數(shù)據(jù)庫中得到的自增長序列值。使用13位序列號來解決時間回撥等問題,如果當(dāng)前時間和上一次是時間相同則序列自增,超過閾值則自旋。
5.3 美團生成UUID
美團基于雪花算法改進,使用“1+41+5+5+12”的方式構(gòu)成UID,在原雪花算法的基礎(chǔ)上,使用5位bit代表機器ID,5位bit代表機房ID,12位序列號代表自增值,由于集群較大,基于Zookeeper組件特性配置機器ID。對于時間回撥問題的解決方案,設(shè)定閾值5毫秒,回撥時間小于5毫秒則等待回撥后重新生成新的UID,超過閾值則拋出異常。
其他大型互聯(lián)網(wǎng)公司生成UID的方案,大部分都是基于Twitter的雪花算法進行改進,其中滴滴使用“時間戳+起點編號+車牌號”生成相應(yīng)的UID,淘寶訂單則使用“時間戳+用戶ID”生成,滴滴則在美團的方案上將號段加載到內(nèi)存中,同時支持多個主節(jié)點模式。微信的UID生成則主要綁定用戶序列號,采用步進式持久化和分號段共享存儲的實現(xiàn)方式。
Part 06●??省級寬帶電視會員管理平臺的應(yīng)用實踐?●
省級寬帶電視會員管理平臺主要管理各省寬帶電視的會員用戶,是一個大型分布式平臺,服務(wù)器跨省分布,數(shù)量眾多,存在時鐘回退問題。因此,本平臺在雪花算法基礎(chǔ)上進行改進,增加時間線的概念,可以同時支持多條時間線并行,很好地解決了時鐘回退問題。具體方案如下:
調(diào)整2位bit代表時間線,最多支持4條時間線,所有時間線設(shè)定統(tǒng)一初始時間,指定一條時間線為統(tǒng)一時間線,根據(jù)該時間線生成相應(yīng)的ID,推進時間進度。機器發(fā)生時鐘回撥時,當(dāng)回撥時間間隔大于設(shè)定的閾值,切換到另一條時間線繼續(xù)生成ID。