新型唯一標識符 ULID 詳解

2024年2月6日 22点热度 0人点赞

什麼是 ULID

ULID(Universally Unique Lexicographically Sortable Identifier,通用唯一字典排序標識符)是一種新型的唯一標識符格式,由 Alizain Feerasta 在2016年提出,在保持唯一性的同時,提供了可排序的特性。ULID 旨在解決 UUID 在某些場景下存在問題,並提供額外的優勢。這使得 ULID 在需要排序的同時保持全局唯一性的場景中非常有用,例如在分佈式系統中用於日志排序、數據庫主鍵等。

ULID 由 128 位組成,通常表示為 26 個字符長的字符串(也可以表示為 32 個十六進制字符的字符串),其中前半部分是時間戳信息,後半部分是隨機序列。這種設計使得 ULID 不僅在全球范圍內具有很高的唯一性,還能根據生成的時間順序進行高效的字典序排序。

ULID 的具體結構

ULID 的格式是固定的,由 128 位組成,通常表示為 26個字符(也可以編碼為32位的十六進制字符串)。這26個字符分為兩部分:

  1. 時間戳部分:前10個字符表示生成 ULID 時的時間戳,精確到毫秒。
  2. 隨機數部分:後16個字符是隨機數,由隨機生成的數字組成,用於確保在相同的毫秒時間戳內生成的 ULID 之間的唯一性。

ULID 使用 Crockford 的 Base32 編碼方案,排除了一些容易混淆的字符,比如小寫的“l”和數字“1”,大寫的“O”和數字“0”,使得 ULID 在視覺上更易於區分,並且在人工輸入時出錯的可能性更小。

ULID 的特點

  • 唯一性:由於時間戳和隨機數的組合,ULID 具有極高的唯一性。在同一毫秒內,即使生成多個 ULID,也不會出現重復的情況。
  • 時序性:ULID 的時間戳部分精確到毫秒,可以反映 ULID 的生成時間。這使得 ULID 具有時序性,方便對實體進行排序和檢索。
  • 可讀性:ULID 由26個字符組成,采用 Crockford 的 base32 編碼,具有較好的可讀性。同時,ULID 的長度較短,便於在日志和數據庫中存儲和展示。
  • 性能:ULID 的生成過程不需要訪問網絡,且時間戳和隨機數的生成速度較快,因此在性能上優於傳統的 UUID。
  • 兼容性:ULID 和 UUID 都是 128位,與現有的 UUID 標準兼容。

ULID 的應用場景

ULID 的設計初衷是為了解決 UUID 在某些場景下表現不佳的問題,尤其是在需要有序標識符的場景,ULID在許多現代應用程序中變得越來越流行,特別是在以下場景:

  • 分佈式系統:在分佈式系統中,使用 ULID 作為實體的唯一標識符,可以保障在不同節點上生成的標識符是唯一的。
  • 數據庫索引:在數據庫中使用 ULID 作為主鍵,不僅可以避免主鍵沖突的問題,也可以進行排序,具有較好的檢索性能和可讀性。
  • 日志記錄:日志系統可以利用 ULID 的可排序性,確保不同機器中同類日志條目的時間順序,可以方便地對日志進行排序和檢索。
  • 雲服務資源標識:在雲環境中標識唯一的虛擬機、容器或者對象存儲文件等。
  • 微服務間通信:用作請求 ID,確保請求在服務間傳遞時具備唯一性和可追溯性。

ULID 的生成方法

ULID的生成方式如下:

  1. 獲取當前時間戳,並轉換為60位二進制形式;
  2. 生成一個80位的隨機或偽隨機數;
  3. 將上述時間和隨機序列拼接起來,形成128位的數據;
  4. 將128位數據轉換為base32編碼的字符串表示。

安全考慮

盡管 ULID 提供了唯一性和可排序性,但在安全性要求較高的應用中使用時,需要註意以下幾點:

  • 隨機部分需要足夠的隨機性,以防止預測未來的 ULID。
  • 時間戳部分可能會泄露信息,攻擊者可能利用這些信息推斷出生成 ULID 的時間。

小結

ULID 作為一種新型的全局唯一標識符,在保證唯一性的同時增加了可排序性。使得ULID 非常適合需要排序和高性能唯一標識符的現代應用程序。隨著分佈式系統和微服務架構的普及,ULID 會變得更加流行。在選擇唯一標識符算法時,應該綜合考慮具體需求,並平衡唯一性、性能和安全性之間的關系。