TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #433 6.88K
Генерация ID в распределённой системе, часть 1

Задача считается сеньорной и входит в категорию system design. Вариантов решения много, и выбирать нужно с умом. Чтобы примерно сориентироваться, обозначу основные варианты и опорные точки.

Над чем подумать в самом начале:

1️⃣ Насколько уникальным должен быть ID?
🔸 В рамках одного сервиса
🔸 Уникальным в пределах системы в течение какого-то времени
🔸 Глобально уникальным в течение всей жизни системы

Два последних варианта влияют на длину id. Чем он короче, тем скорее наступит переполнение. Чем длиннее — тем больше памяти займёт id

2️⃣ Как часто нужно генерировать id?

Влияет на размер и немного на реализацию

3️⃣ Если сущность отдаётся за пределы системы, что видит внешний пользователь?

▫️ id как есть: /user/123
▫️ Декодированный id через Base64: /user/MTIz
▫️ Зашифрованный id: /user/67FA78

4️⃣ Формат

🔸 Возрастающая последовательность

Глобальный счётчик, последовательность в БД или местный AtomicLong

🔸 Случайный набор цифр

Глобально уникальный UUID или локальный Random
✅ Самый быстрый вариант

🔸 Вариации Snowflake

Формат Snowflake придумали в Twitter. В оригинале id формируется как комбинация

timestamp + machine_id + sequence_id
(значения складываются как строки, а не как числа)

❄️ timestamp — количество миллисекунд
❄️ machine_id — id сервера
❄️ sequence_id — возрастающая последовательность

✅ id содержит что-то полезное
✅ Можно сортировать по полям, входящим в id
✅ Глобальная уникальность

Machine id часто меняют на пару (id рабочей машины + id процесса) или (id датацентра + id сервера). Можно вдохновиться и составить свою комбинацию полей

Технические моменты Snowflake

Чтобы timestamp не получался слишком большим, отсчитывайте миллисекунды от какой-то даты отсчёта.

Machine id извлекается в начале работы сервиса
▫️ из распределённого счётчика. Например, из Zookeeper
▫️ из конфига, если при развёртывании ведётся счётчик

Для возрастающей последовательности подойдёт локальный AtomicLong или sequence в БД.

Генерация ID в базе данных

Часто говорят, что генерация id через БД — плохое решение. Все сущности должны проходить через один экземпляр БД, чтобы не было дубликатов, и это ограничивает масштабируемость.

В следующем посте расскажу, как решить эту проблему:)

Генерация через БД подходит, если объект и так сохраняется в базе данных. Если взаимодействий с БД нет (например, нужно id сообщения для кафки), конечно, нужны другие решения.

❓ Как формировать Snowflake id на основе sequence в БД?

Шок контент: в хранимой процедуре. Формирование id — технический момент, а не бизнес-логика. Поэтому такое решение ок.

❓ Как формируется UUID, может ли он повторяться?

Стандарт UUID описывает 5 стратегий генерации UUID. Метод UUID.randomUUID() использует Version 4, генерацию с помощью случайных чисел. Я тоже не доверяю случайным числам, но формулы обещают, что всё будет ок
  • 🔥 55
  • 👍 34
  • ❤ 9
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →