開發者工具 · UUID 產生器
ULID、Snowflake、KSUID 和 UUIDv7:可排序 ID 比較
· 背景
uuid 密碼學 瀏覽器 API
隨機 UUID 不會按建立時間排序,因此多種格式將時間戳記放在前面。這篇文章在佈局、大小、單調性和相容性方面比較了 ULID、Snowflake、KSUID 和 UUIDv7。
隨機 ID 和討厭它們的索引 — 時間排序標識符解決的問題
當新記錄到達時,隨機 v4 UUID 會在 B 樹主鍵上分散插入點,導致頁面分割和重組。在隨機位置插入會降低寫入效能並顯著增加磁碟碎片。高吞吐量資料庫可以容忍這種成本——真正獨立、不協調的識別碼的價格——但成本是真實的。如果您需要 UUID 按建立時間排序,則可以透過新增時間戳前綴來顯著改善索引特性。已經出現了多種格式:ULID、Snowflake、KSUID 和 RFC 9562 v7。每個都在大小(26 字元到 128 位)、時間戳精度(秒到納秒)、UUID 相容性以及 ID 產生器協調是否需要集中化方面做出不同的權衡。資料庫基準測試顯示插入效能顯著提高。
ULID — 48 位毫秒時間戳加上 26 Crockford base32 字元中的 80 隨機位,具有單調選項
ULID(通用唯一字典順序可排序標識符)將 48 位元毫秒時間戳記和 80 位隨機負載編碼為 Crockford base32 的 26 字元。文字表示按字典順序正確排序,使 ULID 適合時間戳排序和可讀性很重要的系統 - 日誌處理、分散式追蹤、標識符需要在面向人類的輸出中輕鬆讀取的微服務。 ULID 提供了一種單調變體,其中在同一毫秒內產生的多個識別碼會增加隨機部分而不是重複,從而確保即使是快速的 ID 突發也能保持嚴格的產生順序。代價是 ULID 不是 UUID:它不適合標準 128 位元 UUID 資料庫列,無需進行編碼轉換。 ULID 精度覆蓋約 8925 年。
Snowflake — 64 位元 ID,來自時間戳記、工作 ID 和序列,以及它們所需的協調
Snowflake 是一個 64 位標識符,最初由 Twitter 設計,結構為 41 位毫秒時間戳記、10 位工作 ID 和 12 位序號。 41 位元時間戳記覆蓋約 69 年,並在 2106 中溢出,需要紀元協調和遷移規劃。 Worker ID 區分不同伺服器或行程產生的識別碼-每個 Snowflake 產生器必須知道自己唯一的 Worker ID,且不能與其他產生器發生衝突。 Snowflake 是 64 位,而不是 128,使其大小只有 UUID 的一半,索引速度更快,並每個標識符的儲存效率更高。它按時間和工作人員 ID 排序,對於按來源路由請求或日誌很有用。缺點是操作性的:必須為每個發電機分配一個工作 ID,時鐘必須保持同步。
KSUID — 具有大隨機負載的秒時間戳,按位元組排序
KSUID(K-可排序唯一標識符)是一個 128 位標識符,由 32 位 Unix 秒時間戳和 96 位隨機負載組成,通常編碼為 27 base62 字元。此格式可依字典順序排序,且隨機部分的大小在加密上是合理的。 KSUID 的採用不如 ULID 或 Snowflake 廣泛,但提供了不同的語義:時間戳很容易解碼為人類可讀的秒(在日誌和調試中有用),並 96 位隨機部分足夠大,使得同一秒中產生的多個 KSUID 在沒有序列協調的情況下實際上具有零重複概率。與 Snowflake 不同,KSUID 不需要工作 ID 協調或集中分配。 KSUID 以秒而不是毫秒為單位進行操作,因此一秒內的多個 ID 會隨機排序,除非您實作額外的邏輯。
UUIDv7 — 適合現有 uuid 欄位和工具的標準追蹤答案
RFC 9562 v7 是一個 128 位標識符,由 48 位 Unix 毫秒時間戳、12 位亞毫秒精度(可用作序列計數器)和 62 隨機位元全部組合而成。它在資料庫中作為字典字串和 128 位元組正確排序。至關重要的是,它是一個有效的 UUID — 它將版本半位元組設定為 7,並將變體位元設為 RFC 9562 標準,使其與處理 UUID 的每個工具、資料庫列和 API 相容。不需要編碼轉換,現有的 UUID 基礎架構不需要修改。如果在同一毫秒內產生多個 v7 標識符,RFC 9562 建議使用亞毫秒欄位作為單調計數器而不是隨機位元。 V7 代表了維護 UUID 相容性的務實選擇。
一毫秒內的單調性 - 每種格式如何處理突發以及為什麼它對於排序保證很重要
單調性是指如果兩個事件按可觀察的順序發生,則它們的 ID 以相同的順序進行比較的屬性。在現代硬體的毫秒粒度上,多個事件通常會在同一時脈週期內發生,因此任何可排序的 ID 方案都必須正確處理亞毫秒排序。 ULID 提供明確單調模式,其中隨機部分遞增而不是隨機化。 Snowflake 包含一個 12 位序號,該序號在一毫秒內遞增。 KSUID 缺乏內建機制,因此除非新增額外的邏輯,否則亞秒事件會隨機排序。 RFC 9562 v7 建議使用亞毫秒欄位作為單調計數器。如果您的系統每秒產生數千個 UUID,則一毫秒內的單調性會顯著影響查詢順序。
這不包括 - 吞吐量基準,這取決於硬體和語言;帖子保持品質
不包括吞吐量基準和效能資料,因為它們嚴重依賴硬體架構、語言實作、資料庫引擎和快取策略。根據您是否測量隨機插入、範圍查詢、索引開銷或實際生產負載下的總吞吐量,資料庫效能特性會有很大差異。這篇文章保持定性,根據其設計從概念上比較格式,而不是提供可能產生誤導的特定環境的數字。實際效能評估需要在您自己的環境中使用您自己的工作負載、程式碼庫和操作約束進行測試。對不同 ID 格式進行基準測試是一項很有價值的練習。
重點:相容性通常決定 — ToolAcre 產生器產生隨機 UUID;使用其格式正確的檢查來確認您的庫中的 UUIDv7 解析為 UUID
相容性通常決定選擇哪種格式。如果您的資料庫架構已經需要 UUID 資料列,則 v7 是在不離開 UUID 生態系統的情況下實現可排序性的現代答案。如果使用自訂 ID 類型建置新系統,ULID 可以提供更小的文字表示形式和毫秒精度優勢。如果您需要 64 位元儲存並可以透過集中分配來管理工作 ID 協調,那麼 Snowflake 是大容量系統中經過驗證的選擇。基本的權衡是在標準相容性(選擇 v7)和替代屬性(例如較小的尺寸(Snowflake)或 base32 可讀性(ULID))之間。根據系統約束和生態系統決策做出選擇。