Skip to content

Feature Snowflake

github-actions[bot] edited this page Jul 15, 2026 · 1 revision

❄️ Snowflake

← Возможности · Главная · Сравнение

63-битный числовой идентификатор раскладки Twitter: 41 бит миллисекунд от эпохи, 5 бит датацентра, 5 бит воркера, 12 бит последовательности. Влезает в BIGINT, сортируется числом, несёт топологию кластера.

Принцип работы

use CloudCastle\Uuid\SnowflakeFactory;

$factory = new SnowflakeFactory(datacenterId: 3, workerId: 7);

$id = $factory->generate();
$id->toInt();            // 864936691172274176 — BIGINT
$id->toString();         // десятичная строка
$id->dateTime();         // момент создания
$id->datacenterId();     // 3
$id->workerId();         // 7
$id->sequence();         // номер в пределах миллисекунды

$parsed = $factory->parse('864936691172274176');   // разбор чужого ID

Эпоха настраивается (по умолчанию 2020-01-01 UTC — запас до ~2089 года):

$factory = new SnowflakeFactory(1, 1, epoch: new DateTimeImmutable('2024-01-01 UTC'));

Поведение на краях — без ожиданий и сна: переполнение последовательности (4096/мс) переносит генерацию в следующую миллисекунду; реальный откат часов прерывается исключением clockMovedBackwards — метка времени в идентификаторе остаётся честной.

Плюсы

  • 8 байт вместо 16: самый компактный сортируемый ID; нативный BIGINT-индекс.
  • Топология (датацентр/воркер) видна из идентификатора.
  • Детерминированные края: никакого usleep() внутри генератора.

Минусы

  • Требует дисциплины узлов: одинаковая пара датацентр/воркер на двух машинах = коллизии.
  • 41 бит времени от эпохи — горизонт ~69 лет.

✅ Рекомендуется

  • Высоконагруженные распределённые системы с BIGINT-ключами.
  • Шардированные БД: идентификатор сам маршрутизирует к узлу-создателю.

❌ Антипаттерны

  • Генерация на неконтролируемых узлах без выделения ID (нужна координация).
  • Snowflake для публичных токенов — момент создания и топология читаемы.

Схема фичи

flowchart LR
    C["Часы (PSR-20/microtime)"] -->|"41 бит мс от эпохи"| F[SnowflakeFactory]
    DC["datacenter 0..31"] --> F
    W["worker 0..31"] --> F
    F -->|"sequence 12 бит"| ID["SnowflakeId (63 бита)"]
Loading

Жизненный цикл

sequenceDiagram
    participant A as Приложение
    participant F as SnowflakeFactory

    A->>F: generate()
    F->>F: часы назад? → исключение
    F->>F: та же мс? → sequence + 1
    F->>F: sequence > 4095? → мс + 1, sequence = 0
    F-->>A: SnowflakeId — строго возрастающий
Loading

Сравнение с аналогами

Возможность Uuid godruoyi/php-snowflake 🏆 Победитель
Раскладка Twitter 41/5/5/12 Паритет
Разбор на поля + метка времени Паритет
Переполнение без usleep() ⚠️ Uuid
PSR-20 часы ⚠️ Uuid
Объект-значение с типами Uuid
Скорость генерации 🥇 ×6.9 🥈 Uuid

Clone this wiki locally