SoupCalc

Générateur d'identifiants Snowflake : l'identifiant distribué 63 bits de Twitter

Qu'est-ce qu'un identifiant Snowflake ?

Un identifiant Snowflake est un entier 63 bits utilisé pour générer des identifiants uniques au sein d'un système distribué sans point de coordination central. Twitter a développé ce format en 2010 pour remplacer les séquences auto-incrémentées des bases de données, qui ne pouvaient pas passer à l'échelle sur des dizaines de serveurs d'application écrivant sur des clusters MySQL partitionnés. Chaque identifiant Snowflake est un entier signé 64 bits dont le bit de poids fort est toujours zéro, laissant 63 bits de charge utile répartis en quatre champs : un décalage d'horodatage de 41 bits, un identifiant de datacenter de 5 bits, un identifiant de machine de 5 bits et un numéro de séquence de 12 bits. Cette disposition permet à un nœud de service Snowflake unique de générer jusqu'à 4 096 identifiants uniques par milliseconde, offrant au système un débit théorique de millions d'identifiants par seconde sur un déploiement de centaines de processus de travail.

Les identifiants Snowflake sont monotones croissants — chaque nouvel identifiant est supérieur au précédent au sein de la même époque — mais ils ne sont pas strictement séquentiels entre les nœuds. Deux machines fonctionnant dans la même milliseconde produiront des identifiants qui s'entrelacent, ce qui est un compromis délibéré : le schéma sacrifie l'ordonnancement parfait au profit d'une indépendance opérationnelle absolue. Chaque processus de travail n'a besoin de connaître que son propre numéro de datacenter et de machine, ainsi que l'heure actuelle, pour produire un identifiant globalement unique sans jamais consulter un pair ou un service de verrouillage.

Anatomie de l'identifiant 63 bits

L'identifiant Snowflake est un entier 63 bits composé des champs suivants, du bit de poids fort au bit de poids faible :

  • Horodatage de 41 bits — millisecondes écoulées depuis une époque personnalisée.
  • Identifiant de datacenter de 5 bits — identifie le datacenter physique hébergeant le processus de travail.
  • Identifiant de machine de 5 bits — identifie l'hôte ou le processus individuel au sein de ce datacenter.
  • Numéro de séquence de 12 bits — un compteur par milliseconde qui se réinitialise à zéro lorsque l'horloge avance.

L'expression exacte qui décrit cette disposition est : un horodatage de 41 bits, un datacenter de 5 bits, une machine de 5 bits et une séquence de 12 bits. Ensemble, ces champs occupent 63 bits, le bit de signe de tête étant mis à zéro pour que l'identifiant s'insère confortablement dans un entier signé 64 bits dans des langages comme Java et C#.

L'époque Twitter et la composante horodatage

Chaque identifiant Snowflake porte un décalage d'horodatage mesuré à partir d'une époque personnalisée : 1288834974657 millisecondes. Cette valeur correspond approximativement au 2010-11-04T04:42:54.657Z et a été choisie pour s'aligner sur le début du déploiement interne de Snowflake chez Twitter. L'utilisation d'une époque personnalisée plutôt que l'époque Unix signifie que le champ d'horodatage de 41 bits peut représenter une plage d'environ 69 ans avant débordement. La valeur d'horodatage maximale que le champ peut contenir est 2^41 moins 1, soit 2 199 023 255 551 millisecondes — environ 69,7 ans après l'époque, ce qui repousse la date de rebouclage aux années 2080.

Pour encoder un horodatage, soustrayez l'époque des millisecondes actuelles de l'époque Unix, puis décalez le résultat vers la gauche de 22 bits pour faire de la place aux trois champs inférieurs. Tout horodatage d'entrée antérieur à l'époque est invalide et doit être rejeté.

Identification des nœuds : datacenter et machine

Le champ datacenter de 5 bits et le champ machine de 5 bits acceptent chacun des valeurs de 0 à 31, produisant un total de 1 024 identifiants de nœuds uniques sur un déploiement. Un processus de travail se voit attribuer un identifiant de datacenter et un identifiant de machine au démarrage, généralement via un fichier de configuration, un service de coordination comme ZooKeeper ou un argument de ligne de commande. L'attribution doit être unique au sein de la flotte : deux processus de travail partageant la même paire (datacenter, machine) produiront des identifiants en collision, sauf si leurs horloges sont déphasées.

Ces champs sont insérés dans l'identifiant en décalant la valeur du datacenter vers la gauche de 17 bits et la valeur de la machine de 12 bits, puis en appliquant un OU binaire des valeurs décalées dans l'entier 63 bits. Le nombre total de nœuds de 1 024 est suffisant pour la plupart des déploiements réels, mais les environnements nécessitant plus de 1 024 processus de travail peuvent emprunter des bits au champ de séquence ou au champ d'horodatage, au prix du débit ou de la plage d'époque.

Le compteur de séquence et les limites d'horloge

Le champ de séquence de 12 bits est le cheval de trait de la conception Snowflake. Il s'étend de 0 à 4 095 et s'incrémente de un pour chaque identifiant généré dans la même milliseconde. Lorsque la séquence atteint 4 095, le processus de travail tourne dans une boucle d'attente active jusqu'à ce que l'horloge système passe à la milliseconde suivante, moment auquel la séquence se réinitialise à zéro et la génération reprend. Cela donne à un nœud unique un taux de rafale maximal de 4 096 identifiants par milliseconde.

La dérive d'horloge et le retour en arrière d'horloge sont les deux modes de défaillance les plus significatifs de l'algorithme Snowflake. Si l'horloge système recule — que ce soit en raison d'une correction NTP, d'une migration de machine virtuelle ou d'un changement manuel — un processus de travail pourrait générer un identifiant avec un horodatage inférieur au dernier qu'il a produit, rompant ainsi la garantie d'unicité. La parade standard consiste à interrompre la génération d'identifiants et à lever une erreur lorsqu'un retour en arrière d'horloge est détecté, en refusant de servir les requêtes jusqu'à ce que l'horloge rattrape le dernier horodatage observé. Un déploiement qui ne peut tolérer d'indisponibilité devrait envisager un service de temps dédié ou une couche d'horloge logique.

Exemple détaillé

Considérons les valeurs d'entrée suivantes : un horodatage Unix-époque de 1700000000000 millisecondes, un identifiant de datacenter de 7, un identifiant de machine de 13 et un numéro de séquence de 4095.

Encodage. Calculer d'abord le décalage d'horodatage : 1700000000000 moins l'époque Snowflake 1288834974657 égale 411165025343. Décaler ce décalage vers la gauche de 22 bits pour obtenir 1724551110456246272. Décaler la valeur du datacenter 7 vers la gauche de 17 bits pour obtenir 917504. Décaler la valeur de la machine 13 vers la gauche de 12 bits pour obtenir 53248. Le numéro de séquence ne nécessite aucun décalage. Combiner les quatre termes avec un OU binaire pour produire l'identifiant Snowflake final : 1724551110457221119.

Décodage. Pour récupérer les champs d'origine à partir de l'identifiant 1724551110457221119, masquer les 12 bits de poids faible pour extraire la séquence : 4095. Décaler vers la droite de 12 bits et masquer les 5 bits de poids faible pour récupérer l'identifiant de machine : 13. Décaler vers la droite de 17 bits et masquer les 5 bits de poids faible pour récupérer l'identifiant de datacenter : 7. Décaler vers la droite de 22 bits pour obtenir le décalage d'horodatage : 411165025343. Ajouter l'époque 1288834974657 pour récupérer l'horodatage Unix-époque d'origine : 1700000000000.

L'aller-retour est exact car chaque champ tient dans la largeur de bits qui lui est allouée et aucune information n'est perdue lors de l'encodage.

Précision et limitations

Le schéma d'encodage Snowflake est déterministe et réversible à condition que toutes les entrées se situent dans leurs plages valides. Le décalage d'horodatage doit être un entier non négatif de 41 bits ; les identifiants de datacenter et de machine doivent être compris entre 0 et 31 ; et la séquence doit être comprise entre 0 et 4 095. Toute entrée hors de ces limites est rejetée comme invalide.

Le schéma ne prend pas en compte les secondes intercalaires ni la précision inférieure à la milliseconde. Il repose sur l'horloge du système hôte, qui peut dériver ou être ajustée par des processus externes. Dans les déploiements où l'horloge système est avancée par un grand saut NTP, le champ de décalage avancera correctement, mais le compteur de séquence sera resté inactif pendant l'intervalle, laissant une période d'identifiants non émis. Ceci est sans conséquence pour l'unicité mais crée une discontinuité dans la chronologie des identifiants.

Les processus de travail partitionnés par le réseau qui partagent le même tuple (datacenter, machine) produiront des identifiants en collision s'ils sont actifs simultanément. L'espace d'identifiants fournit 1 024 emplacements de nœuds uniques, et dépasser ce nombre nécessite une variante personnalisée de la disposition des bits.

Sources

Notice éditoriale

Cet article décrit le format d'identifiant Snowflake tel que défini dans l'implémentation de référence de Twitter de 2010. La disposition des bits et la valeur d'époque sont tirées directement du code source Scala open source. L'exemple détaillé a été vérifié par un calcul manuel qui encode et décode les mêmes valeurs pour confirmer l'aller-retour. La discussion sur le retour en arrière d'horloge et les limites de nœuds reflète l'expérience opérationnelle documentée dans la littérature d'ingénierie sur la génération d'identifiants distribués.

L'article ne couvre pas les implémentations tierces ni les variantes qui modifient la disposition des bits — telles que celles qui utilisent un identifiant de machine de 10 bits, une époque différente ou un champ d'identifiant de travailleur tiré d'un service de coordination. Ces variantes sortent du cadre de la spécification originale de Snowflake. Auteur : Équipe éditoriale de SoupCalc Dernière révision : 11 août 2026.