ULID-分布式系統(tǒng)中生成全局唯一標識符更好的選擇
ULID與UUID
ULID (Universally Unique Lexicographically Sortable Identifier) 是一種用于生成全局唯一標識符的算法。它結(jié)合了時間戳和隨機數(shù),以便生成的標識符在排序時能夠按照時間順序排列。ULID 的格式為 48 個字符的字符串,其中包含 10 個時間戳字符和 16 個隨機數(shù)字符。
ULID 的格式如下:
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
10 chars 16 chars
ULID 的時間戳部分使用當前時間與 Unix Epoch (1970-01-01) 的差值來表示,而隨機數(shù)部分則使用隨機生成的字符來確保唯一性。
ULID 的設(shè)計目的是為了在分布式系統(tǒng)中生成全局唯一標識符,并且能夠在數(shù)據(jù)庫中進行排序和索引。
UUID(Universally Unique Identifier)是一種128位的標識符,通常用于唯一標識信息。它是由一組數(shù)字和字母組成的32個字符的字符串,通常以連字符分隔為五段,形如8-4-4-4-12的格式。UUID的生成算法保證了在所有的時間和空間中都是唯一的。
在計算機科學(xué)中,UUID經(jīng)常用于分布式系統(tǒng)中的唯一標識,比如數(shù)據(jù)庫中的主鍵、消息隊列中的消息標識等。UUID的唯一性和分散性使得它在分布式系統(tǒng)中具有很高的價值。
UUID有不同的版本:
- UUIDv1:基于時間戳和MAC地址生成,可能存在隱私安全風(fēng)險。
- UUIDv3:基于名字空間和名稱的MD5散列值生成。
- UUIDv4:基于隨機數(shù)生成,具有較高的唯一性。
- UUIDv5:基于名字空間和名稱的SHA-1散列值生成。
每個版本的UUID都有特定的生成算法和格式要求,用于確保生成的UUID在分布式系統(tǒng)范圍內(nèi)是唯一的。
ULID對比UUID
ULID是一種用于生成全局唯一標識符的算法,它結(jié)合了時間戳和隨機數(shù),以便在分布式系統(tǒng)中生成排序良好的唯一標識符。ULID的格式為26個字符的字符串,其中包含了時間戳和隨機數(shù)。
相比之下,UUID是一種標準化的全局唯一標識符,它通?;陔S機數(shù)或者基于時間戳和計算機的MAC地址等信息生成。UUID的格式為32個字符的字符串,通常以32位的十六進制數(shù)字表示。
ULID相對于UUID的優(yōu)勢在于它是可排序的,因為它包含了時間戳信息,這使得在分布式系統(tǒng)中對生成的標識符進行排序和檢索更加高效。而UUID則更加偏向于全局唯一性,但在分布式系統(tǒng)中可能會存在排序和檢索的性能問題。
ULID特性和規(guī)范
- 「全局唯一性」:ULID生成的標識符在全局范圍內(nèi)是唯一的,可以用于標識數(shù)據(jù)記錄、實體或事件。
- 「按字典順序可排序」:ULID是按照時間戳和隨機數(shù)生成的,因此可以按照字典順序進行排序,適合用作數(shù)據(jù)庫主鍵或索引。
- 「可讀性」:ULID使用了基于Crockford's Base32的編碼,因此生成的標識符可以以字符串形式呈現(xiàn),并且相對易讀。
- 「時間有序性」:ULID的前部分包含了時間戳信息,因此可以根據(jù)ULID推斷出生成時的時間。
ULID的格式通常為01AN4Z07BY,由10位時間戳和16位隨機數(shù)組成。其具體生成算法可以參考ULID規(guī)范。
ULID規(guī)范:
- 128位長度,由時間戳和隨機數(shù)組成。
- 使用時間戳來保證排序,使用隨機數(shù)來保證唯一性。
- 采用Crockford's Base32編碼,用于生成可打印的ASCII字符串。
ULID的格式如下:
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
10 chars 16 chars
ULID的時間戳部分使用當前時間與Unix紀元(1970-01-01)的差值來表示,精確到毫秒級。隨機數(shù)部分使用安全的隨機數(shù)生成算法來保證唯一性。ULID的設(shè)計旨在在分布式系統(tǒng)中生成全局唯一標識符,并且可以按時間排序。
- 時間戳:占據(jù)前48位,是一個自增的UTC時間戳,精確到毫秒。
- 隨機數(shù):占據(jù)后80位,使用隨機數(shù)生成算法生成的隨機數(shù)。
ULID的組成如下:
ULID由32個可打印字符組成,使用Crockford's Base32編碼表示。具體格式為:
tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
其中,前面的時間戳部分占據(jù)了前面的48位,后面的隨機數(shù)部分占據(jù)了后面的80位。
ULID應(yīng)用
ULID通常應(yīng)用于需要生成全局唯一標識符并且需要按時間排序的各種分布式系統(tǒng)場景,例如:
- 數(shù)據(jù)庫主鍵:在分布式系統(tǒng)中,可以將ULID作為數(shù)據(jù)庫表的主鍵,確保每條記錄都有唯一標識,并且可以按照生成時間進行排序。
- 日志跟蹤:在日志系統(tǒng)中,可以使用ULID作為日志條目的唯一標識符,便于跟蹤和排序日志。
- 分布式系統(tǒng)中的事務(wù)標識:在分布式系統(tǒng)中,可以使用ULID作為事務(wù)的唯一標識符,確保每個事務(wù)都有全局唯一的標識。
在Java中使用ULID需要在項目中添加ULID庫的依賴,可以使用Maven或Gradle進行添加。
使用Maven添加ULID庫的依賴:
<dependency>
<groupId>de.huxhorn.sulky</groupId>
<artifactId>de.huxhorn.sulky.ulid</artifactId>
<version>2.0.0</version>
</dependency>
使用Gradle添加ULID庫的依賴:
implementation 'de.huxhorn.sulky:de.huxhorn.sulky.ulid:2.0.0'
添加好ULID庫的依賴,就可以在Java代碼中使用ULID來生成唯一標識符。
import de.huxhorn.sulky.ulid.ULID;
public class Main {
public static void main(String[] args) {
ULID.Value ulid = new ULID().nextValue();
System.out.println(ulid);
}
}