Generador d'ID Snowflake per a sistemes distribuïts

Genera i analitza IDs Snowflake de Twitter, identificadors únics de 64 bits utilitzats en sistemes distribuïts. Aquesta eina et permet crear nous IDs Snowflake i analitzar els existents, proporcionant informació sobre els seus components de caràcter temporal, ID de màquina i número de seqüència.

Generador d'ID de Snowflake

Generador d'ID de Snowflake

Optional: Unix timestamp in milliseconds (defaults to current time)
📚

Documentació

Generador d'ID Snowflake

Introducció

Un ID Snowflake és un identificador únic utilitzat en sistemes distribuïts, originalment desenvolupat per Twitter. Aquesta eina permet generar i analitzar IDs Snowflake, que són enters de 64 bits compostos per un caràcter temporal, un ID de màquina i un número de seqüència.

Com funcionen els IDs Snowflake

Els IDs Snowflake són enters de 64 bits estructurats de la següent manera:

  • 41 bits: Caràcter temporal (mil·lisegons des d'una època personalitzada)
  • 10 bits: ID de màquina (5 bits per a l'ID del centre de dades, 5 bits per a l'ID del treballador)
  • 12 bits: Número de seqüència

Aquesta estructura permet la generació d'aproximadament 4.096 IDs únics per mil·lisegon per màquina.

Ús del Generador d'ID Snowflake

  1. (Opcional) Establiu una època personalitzada (el valor per defecte és l'època de Twitter: 2010-11-04T01:42:54.657Z)
  2. Introduïu un ID de màquina (0-31) i un ID de centre de dades (0-31)
  3. Feu clic a "Generar" per crear un nou ID Snowflake
  4. L'ID generat i els seus components es mostraran

Per analitzar un ID Snowflake existent, introduïu-lo al camp "Analitzar ID" i feu clic a "Analitzar".

Fórmula

L'ID Snowflake es construeix mitjançant operacions de bits:

1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2

On:

  • timestamp és el nombre de mil·lisegons des de l'època
  • datacenterId és un enter de 5 bits (0-31)
  • workerId és un enter de 5 bits (0-31)
  • sequence és un enter de 12 bits (0-4095)

Càlcul

El generador d'ID Snowflake realitza els següents passos:

  1. Obteniu el caràcter temporal actual en mil·lisegons
  2. Assegureu-vos que el caràcter temporal sigui més gran que el darrer caràcter temporal utilitzat (per a la unicitat)
  3. Si el caràcter temporal és el mateix que l'últim, incrementeu el número de seqüència
  4. Si el número de seqüència desborda (arriba a 4096), espereu el següent mil·lisegon
  5. Combineu els components mitjançant operacions de bits per crear l'ID final

Casos d'ús

Els IDs Snowflake són particularment útils en:

  1. Sistemes distribuïts: Generar IDs únics a través de múltiples màquines sense coordinació
  2. Dades d'alt volum: Crear IDs ordenables per a grans conjunts de dades
  3. Microserveis: Assegurar identificadors únics a través de diferents serveis
  4. Fragmentació de bases de dades: Utilitzar el component de caràcter temporal o ID de màquina per a una fragmentació eficient

Alternatives

Si bé els IDs Snowflake són potents, altres sistemes de generació d'ID inclouen:

  1. UUID (Identificador Únic Universal): Útil quan es necessita generació distribuïda sense ordenabilitat
  2. IDs de bases de dades d'auto-increment: Simples però limitats a instàncies de bases de dades individuals
  3. ULID (Identificador Universal Únic Lexicogràficament Ordenable): Similar a Snowflake, però amb una estructura diferent

Casos límit i limitacions

  1. Sincronització del rellotge: Els IDs Snowflake depenen del temps del sistema. Si el rellotge es mou cap enrere a causa d'ajustos NTP o canvis d'hora d'estiu, pot causar problemes amb la generació d'ID.

  2. Problema de l'any 2038: El caràcter temporal de 41 bits s'exhaurirà el 2079 (suposant l'època de Twitter). Els sistemes que utilitzen IDs Snowflake haurien de planificar aquesta eventualitat.

  3. Col·lisions d'ID de màquina: En sistemes distribuïts grans, assegurar IDs de màquina únics pot ser un repte i pot requerir coordinació addicional.

  4. Desbordament de seqüència: En escenaris d'alt rendiment, és possible esgotar les 4096 seqüències per mil·lisegon, cosa que pot causar retards.

  5. No monotonicitat entre màquines: Si bé els IDs són monotònicament creixents en una sola màquina, poden no ser estrictament monotònics entre múltiples màquines.

Història

Els IDs Snowflake es van introduir per Twitter el 2010 per abordar la necessitat d'identificadors únics distribuïts i ordenables en el temps. Des de llavors, han estat adoptats i adaptats per moltes altres empreses i projectes.

Exemples

Aquí teniu implementacions de generadors d'ID Snowflake en diversos llenguatges:

1class SnowflakeGenerator {
2  constructor(epoch = 1288834974657, datacenterIdBits = 5, workerIdBits = 5, sequenceBits = 12) {
3    this.epoch = BigInt(epoch);
4    this.datacenterIdBits = datacenterIdBits;
5    this.workerIdBits = workerIdBits;
6    this.sequenceBits = sequenceBits;
7    this.maxDatacenterId = -1n ^ (-1n << BigInt(datacenterIdBits));
8    this.maxWorkerId = -1n ^ (-1n << BigInt(workerIdBits));
9    this.sequenceMask = -1n ^ (-1n << BigInt(sequenceBits));
10    this.workerIdShift = BigInt(sequenceBits);
11    this.datacenterIdShift = BigInt(sequenceBits + workerIdBits);
12    this.timestampLeftShift = BigInt(sequenceBits + workerIdBits + datacenterIdBits);
13    this.sequence = 0n;
14    this.lastTimestamp = -1n;
15  }
16
17  nextId(datacenterId, workerId) {
18    let timestamp = this.currentTimestamp();
19
20    if (timestamp < this.lastTimestamp) {
21      throw new Error('El rellotge s\'ha mogut enrere. Es nega a generar l\'id');
22    }
23
24    if (timestamp === this.lastTimestamp) {
25      this.sequence = (this.sequence + 1n) & this.sequenceMask;
26      if (this.sequence === 0n) {
27        timestamp = this.tilNextMillis(this.lastTimestamp);
28      }
29    } else {
30      this.sequence = 0n;
31    }
32
33    this.lastTimestamp = timestamp;
34
35    return ((timestamp - this.epoch) << this.timestampLeftShift) |
36           (BigInt(datacenterId) << this.datacenterIdShift) |
37           (BigInt(workerId) << this.workerIdShift) |
38           this.sequence;
39  }
40
41  tilNextMillis(lastTimestamp) {
42    let timestamp = this.currentTimestamp();
43    while (timestamp <= lastTimestamp) {
44      timestamp = this.currentTimestamp();
45    }
46    return timestamp;
47  }
48
49  currentTimestamp() {
50    return BigInt(Date.now());
51  }
52}
53
54// Ús
55const generator = new SnowflakeGenerator();
56const id = generator.nextId(1, 1);
57console.log(`ID Snowflake generat: ${id}`);
58

Diagrama

Aquí teniu una representació visual de l'estructura de l'ID Snowflake:

Caràcter temporal (41 bits) ID de màquina (10 bits) Seqüència (12 bits)

Estructura de l'ID Snowflake de 64 bits

Referències

  1. "Anunciant Snowflake." Blog d'Enginyeria de Twitter, https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
  2. "ID Snowflake." Viquipèdia, https://ca.wikipedia.org/wiki/Snowflake_ID
  3. "Generació d'ID distribuïda en microserveis." Medium, https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f