Русский

Инструменты разработчика · Генератор UUID

ULID, Snowflake, KSUID и UUIDv7: сравнение сортируемых идентификаторов

· Фон

uuid криптография API-интерфейс браузера

Четыре макета идентификаторов рядом: ULID, Snowflake, KSUID и UUIDv7, с отображением разделов временной метки и случайности.
Оригинальная векторная иллюстрация ToolAcre

Случайные UUID не сортируются по времени создания, поэтому в некоторых форматах сначала ставится временная метка. В этом посте сравниваются ULID, Snowflake, KSUID и UUIDv7 по макету, размеру, монотонности и совместимости.

Случайные идентификаторы и индекс, который их ненавидит — проблема, которую решают упорядоченные по времени идентификаторы

Случайные UUID версии 4 разбрасывают точки вставки по первичному ключу B-дерева по мере поступления новых записей, вызывая разделение страниц и реорганизацию. Вставки в произвольные позиции снижают производительность записи и значительно увеличивают фрагментацию диска. Базы данных с высокой пропускной способностью терпят эту цену — цену действительно независимых, нескоординированных идентификаторов, — но цена реальна. Если вам нужно, чтобы UUID сортировались по времени создания, вы можете значительно улучшить характеристики индекса, добавив префикс метки времени. Появилось несколько форматов: ULID, Snowflake, KSUID и RFC 9562 v7. Каждый из них имеет разные компромиссы по размеру (символы 26 и 128 bits), точности временной метки (от секунд до наносекунд), совместимости UUID и необходимости централизации координации генератора идентификаторов. Тесты базы данных показывают, что производительность вставки значительно улучшается.

ULID — 48-битная миллисекундная временная метка плюс 80 случайные биты в 26 символах Crockford base32 с монотонной опцией

ULID (универсальный уникальный лексикографически сортируемый идентификатор) кодирует 48-битную миллисекундную метку времени и 80-битную случайную полезную нагрузку в 26 символах Crockford base32. Текстовое представление правильно сортируется в лексикографическом порядке, что делает ULID подходящими для систем, где порядок меток времени и читаемость имеют значение — обработка журналов, распределенная трассировка, микросервисы, где идентификаторы должны быть легко читаемы в выводе, доступном для человека. ULID предлагает монотонный вариант, в котором несколько идентификаторов, сгенерированных в течение одной и той же миллисекунды, увеличивают случайную часть, а не повторяются, гарантируя, что даже быстрые пакеты идентификаторов сохраняют строгий порядок генерации. Компромисс заключается в том, что ULID не является UUID: он не помещается в стандартный 128-битный столбец базы данных UUID без преобразования кодировки. Точность ULID охватывает примерно 8925 лет.

Снежинка — 64-битные идентификаторы из метки времени, идентификатора рабочего и последовательности, а также требуемая для них координация.

Snowflake — это 64-битный идентификатор, первоначально разработанный Twitter, структурированный как 41-битная временная метка в миллисекундах, 10-битный рабочий идентификатор и 12-битный порядковый номер. 41-битная временная метка охватывает примерно 69 лет и переполняется в 2106, что требует координации эпохи и планирования миграции. Идентификатор работника различает идентификаторы, генерируемые разными серверами или процессами — каждый генератор Snowflake должен знать свой собственный уникальный идентификатор работника, не конфликтуя с другими. Snowflake — это 64 bits вместо 128, что делает его вдвое меньше UUID, быстрее индексируется и более эффективно использует хранилище для каждого идентификатора. Он сортируется по времени и идентификатору работника, что полезно для маршрутизации запросов или журналов по источнику. Недостаток операционный: каждому генератору должен быть присвоен рабочий идентификатор, часы должны быть синхронизированы.

KSUID — временная метка в секундах с большой случайной полезной нагрузкой, отсортированной в байтах.

KSUID (уникальный идентификатор K-Sortable) — это 128-битный идентификатор, состоящий из 32-битной второй временной метки Unix и 96-битной случайной полезной нагрузки, обычно кодируемой как 27 символы base62. Формат сортируется в лексикографическом порядке, а случайная часть является криптографически надежной для своего размера. KSUID менее широко распространен, чем ULID или Snowflake, но предлагает отличную семантику: временная метка легко декодируется до удобочитаемой секунды (полезно в журналах и отладке), а случайная часть 96 достаточно велика, чтобы несколько KSUID, сгенерированных в одну и ту же секунду, имели фактически нулевую вероятность дублирования без координации последовательностей. В отличие от Snowflake, KSUID не требует координации идентификатора работника или централизованного распределения. KSUID работает с секундами, а не с миллисекундами, поэтому несколько идентификаторов в течение одной секунды сортируются случайным образом, если вы не реализуете дополнительную логику.

UUIDv7 — стандартизированный ответ, который подходит для существующих столбцов uuid и инструментов.

RFC 9562 v7 — это 128-битный идентификатор, состоящий из 48-битной миллисекундной метки времени Unix, 12 bits субмиллисекундной точности (может использоваться в качестве счетчика последовательности) и 62 случайных битов, объединенных вместе. Он правильно сортируется как в виде лексикографической строки, так и в виде 128-битных байтов в базах данных. Важно отметить, что это действительный UUID — он устанавливает полубайт версии на 7, а биты варианта — на RFC 9562 стандарта, что делает его совместимым со всеми инструментами, столбцами базы данных и API, которые обрабатывают UUID. Никакого преобразования кодировки не требуется, и существующая инфраструктура UUID не требует изменений. Если за одну и ту же миллисекунду генерируется несколько идентификаторов v7, RFC 9562 рекомендует использовать субмиллисекундное поле в качестве монотонного счетчика, а не случайных битов. V7 представляет собой прагматичный выбор для обеспечения совместимости с UUID.

Монотонность в пределах одной миллисекунды — как каждый формат обрабатывает всплески и почему это важно для гарантий заказа

Монотонность — это свойство, заключающееся в том, что если два события происходят в наблюдаемом порядке, их идентификаторы сравниваются в том же порядке. При детализации на уровне миллисекунд на современном оборудовании несколько событий регулярно происходят в течение одного и того же такта, поэтому любая схема сортируемого идентификатора должна правильно обрабатывать субмиллисекундный порядок. ULID предлагает явный монотонный режим, в котором случайная часть увеличивается, а не рандомизируется. Snowflake включает 12-битный порядковый номер, который увеличивается с шагом в миллисекунду. В KSUID отсутствует встроенный механизм, поэтому события, происходящие менее секунды, сортируются случайным образом, если не добавлена ​​дополнительная логика. RFC 9562 v7 рекомендует использовать поле субмиллисекундного значения в качестве монотонного счетчика. Если ваша система генерирует тысячи UUID в секунду, монотонность в течение миллисекунды существенно влияет на порядок запросов.

Что здесь не распространяется — тесты пропускной способности, которые зависят от оборудования и языка; пост остается качественным

Тесты пропускной способности и данные о производительности не включены, поскольку они сильно зависят от аппаратной архитектуры, реализации языка, ядра базы данных и стратегии кэширования. Характеристики производительности базы данных существенно различаются в зависимости от того, измеряете ли вы случайные вставки, запросы диапазона, издержки индекса или общую пропускную способность при реальной производственной нагрузке. Пост остается качественным: форматы сравниваются концептуально на основе их дизайна, а не приводятся цифры, относящиеся к конкретной среде, которые могут ввести в заблуждение. Реальная оценка производительности требует тестирования в вашей собственной среде с вашей собственной рабочей нагрузкой, кодовой базой и эксплуатационными ограничениями. Сравнительный анализ различных форматов идентификаторов — ценное занятие.

Вывод: часто решает совместимость — генератор ToolAcre генерирует случайные UUID; используйте его правильно сформированную проверку, чтобы подтвердить, что UUIDv7 из вашей библиотеки анализируется как UUID

Совместимость часто решает, какой формат выбрать. Если ваша схема базы данных уже требует столбцов UUID, v7 — это современный ответ на возможность сортировки, не выходя из экосистемы UUID. При создании новой системы с пользовательскими типами идентификаторов ULID предлагает меньшее текстовое представление и преимущества точности до миллисекунды. Если вам требуется 64-битное хранилище и вы можете управлять координацией идентификаторов работников посредством централизованного распределения, Snowflake — проверенный выбор в системах большого объема. Фундаментальный компромисс заключается между стандартной совместимостью (выберите v7) и альтернативными свойствами, такими как меньший размер (Snowflake) или читаемость base32 (ULID). Делайте выбор на основе системных ограничений и экосистемных решений.