En réponse aux questions de performances qui se posent souvent lors de l'utilisation, je donne les trois ensembles de bonnes pratiques suivants :
❄ Si l'exigence de génération d'ID ne dépasse pas 5 W/s, il n'est pas nécessaire de modifier les paramètres de configuration.
❄ Si elle dépasse 5W pièces/s et est inférieure à 50W pièces/s, il est recommandé de modifier : SeqBitLength=10
❄ S'il dépasse 50W bits/s et est proche de 500W bits/s, il est recommandé de modifier : SeqBitLength=12
En résumé, augmenter SeqBitLength entraînera de meilleures performances, mais les ID générés seront plus longs.
❄ Il s'agit d'un algorithme de flocon de neige optimisé (dérive de flocon de neige), qui génère des identifiants plus courts et plus rapides.
❄ Prend en charge l'expansion automatique des environnements de conteneurs tels que k8s (enregistrement automatique de WorkerId) et peut générer un identifiant numérique unique dans un environnement autonome ou distribué.
❄ Prend en charge nativement C#/Java/Go/C/Rust/Python/Node.js/PHP (extension C)/SQL/ et d'autres langages, et fournit des appels de bibliothèque dynamique sécurisés multithread (FFI).
❄ Compatible avec tous les algorithmes de flocon de neige (mode segment de nombre ou mode classique, grands ou petits fabricants), vous pourrez effectuer n'importe quelle mise à niveau ou changement à l'avenir.
❄ Il s'agit de l'outil de génération d'ID Snowflake le plus complet de l'histoire de l'informatique. 【En août 2022】
? En tant qu'architecte, vous souhaitez résoudre le problème des clés primaires uniques dans une base de données, notamment dans un système distribué comportant plusieurs bases de données.
? Vous souhaitez que la clé primaire de la table de données utilise le moins d'espace de stockage, indexe plus rapidement et sélectionne, insère et mette à jour plus rapidement.
? Vous devez considérer que lors de la division de bases de données et de tables (fusion de bases de données et de tables), la valeur de la clé primaire peut être utilisée directement et peut refléter le timing de l'entreprise.
? Si une telle valeur de clé primaire est trop longue et dépasse la valeur maximale du type Number js frontal, le type Long doit être converti en type String, et vous vous sentirez un peu frustré.
? Bien que Guid puisse s'auto-incrémenter, il prend beaucoup de place et la vitesse d'indexation est lente. Vous ne souhaitez pas l'utiliser.
? Il peut y avoir plus de 50 instances d'application, et chaque requête simultanée peut atteindre 10 W/s.
? Pour déployer des applications dans un environnement de conteneur, prendre en charge la réplication horizontale et l'expansion automatique.
? Vous ne voulez pas compter sur l'opération d'incrémentation automatique de Redis pour obtenir des identifiants de clé primaire continus, car les identifiants continus présentent des risques pour la sécurité des données d'entreprise.
? Vous souhaitez que le système fonctionne pendant plus de 100 ans.
L'ID généré est trop long.
La quantité de concurrence instantanée n’est pas suffisante.
Le problème de rappel de l'heure ne peut pas être résolu.
La génération post-supplémentaire d’ID de précommande n’est pas prise en charge.
Peut s'appuyer sur des systèmes de stockage externes.
✔ Nombres entiers, augmentant de manière monotone avec le temps (pas nécessairement continus), plus courts et ne dépasseront pas la valeur maximale du type js Number dans 50 ans. (configuration par défaut)
✔ Plus rapide, 2 à 5 fois plus rapide que l'algorithme de flocon de neige traditionnel, 500 000 peuvent être générés en 0,1 seconde (basé sur l'i7 basse tension de 8ème génération).
✔ Prise en charge du traitement des rappels temporels. Par exemple, si l'heure du serveur est retardée d'1 seconde, cet algorithme peut s'adapter automatiquement pour générer un identifiant unique pour l'heure critique.
✔Prend en charge l'insertion manuelle de nouveaux identifiants. Lorsque l'entreprise a besoin de générer de nouveaux identifiants dans un délai historique, les bits réservés de cet algorithme peuvent générer 5 000 identifiants par seconde.
✔ Ne repose sur aucun cache ou base de données externe. (La bibliothèque dynamique qui enregistre automatiquement WorkerId dans l'environnement k8s s'appuie sur Redis)
✔ Fonctions de base, prêtes à l'emploi, aucun fichier de configuration, connexion à une base de données, etc.
(Paramètres : séquence d'augmentation automatique de 10 bits, 1 000 valeurs maximales de dérive)
Demandes continues | 5K | 5W | 50W |
---|---|---|---|
Algorithme de flocon de neige traditionnel | 0,0045s | 0,053 s | 0,556 s |
Algorithme de dérive de neige | 0,0015s | 0,012 s | 0,113s |
? Performance ultime : 500 W/s ~ 3000 W/s. (Toutes les données de test sont calculées sur la base de la basse tension i7 de 8e génération)
? Lorsque le rappel de l'heure du système se produit, l'algorithme utilise le numéro de séquence réservé de la série temporelle passée pour générer un nouvel identifiant.
? Le numéro d'identification généré par le rappel est placé en premier par défaut et peut également être ajusté pour l'être plus tard.
? Permettre que le temps soit ramené à la base prédéfinie de cet algorithme (les paramètres sont réglables).
? L'ID généré par cet algorithme est un entier (occupe jusqu'à 8 octets d'espace). Voici l'ID généré en fonction de la configuration par défaut :
129053495681099 (运行1年,长度:15)
387750301904971 (运行3年,长度:15)
646093214093387 (运行5年,长度:15)
1292658282840139 (运行10年,长度:16)
9007199254740992 (运行70年,达到 js Number 最大值,长度:16)
165399880288699493 (运行1000年,等同普通雪花算法运行1年,长度:18)
? La valeur ID générée par cet algorithme est comprise entre 1 % et 10 % de la valeur maximale du nombre js, soit un millième de la valeur de l'algorithme de flocon de neige ordinaire, mais la vitesse de génération est plus rapide que celle de l'algorithme de flocon de neige ordinaire.
? La valeur maximale du type js Number : 9007199254740992. Cet algorithme peut prendre 70 ans pour atteindre la valeur js Number Max tout en conservant les performances de concurrence (5W+/0,01s) et un maximum de 64 WorkerIds (6 bits).
? 每增加 1位 WorkerIdBitLength 或 SeqBitLength,生成的ID数字值将会乘以2(基础长度可参考前一节“ID示例”),反之则除以2。
L'explication de la durée d'utilisation fait référence au moment où le numéro d'identification généré peut croître pour dépasser la valeur maximale de long (signé 64 bits, 8 octets).
• Dans la configuration par défaut, 71 000 ID uniques sont disponibles.
? Lors de la prise en charge de 1 024 nœuds de travail, les identifiants sont disponibles pendant 4 480 ans sans duplication.
? Lors de la prise en charge de 4 096 nœuds de travail, les identifiants sont disponibles pendant 1 120 ans sans duplication.
❄ WorkerIdBitLength , la longueur en bits du code machine, détermine la valeur maximale de WorkerId, la valeur par défaut est 6 et la plage de valeurs est [1, 19]. En fait, certaines langues utilisent le type ushort (uint16) non signé pour recevoir. ce paramètre, donc la valeur maximale est 16. Si Si signé court (int16) est utilisé, la valeur maximale est 15.
❄ WorkerId , le code machine, le paramètre le plus important , pas de valeur par défaut, doit être globalement unique (ou unique au sein du même DataCenterId), doit être défini par programme , la condition par défaut (WorkerIdBitLength prend la valeur par défaut), la valeur maximale est 63, la valeur maximale théorique est 2^WorkerIdBitLength -1 (les différents langages d'implémentation peuvent être limités à 65535 ou 32767, le principe est le même que la règle WorkerIdBitLength). Elle ne peut pas être la même sur différentes machines ou différentes instances d'application. Vous pouvez configurer cette valeur via l'application ou obtenir la valeur en appelant un service externe. En réponse au besoin d'enregistrement automatique de WorkerId, cet algorithme fournit une implémentation par défaut : enregistrer automatiquement la bibliothèque dynamique de WorkerId via Redis, voir "ToolsAutoRegisterWorkerId" pour plus de détails.
Note spéciale : Si un serveur déploie plusieurs services indépendants, vous devez spécifier un WorkerId différent pour chaque service.
❄ SeqBitLength , longueur de bit de séquence, valeur par défaut 6 , plage de valeurs [3, 21] (recommandé pas moins de 4), détermine le nombre d'ID générés par milliseconde. Si le nombre de requêtes par seconde ne dépasse pas 5W, conservez simplement la valeur par défaut de 6 ; s'il dépasse 5W et ne dépasse pas 50W, il est recommandé d'attribuer une valeur de 10 ou plus, et ainsi de suite. Exigence de règle : WorkerIdBitLength + SeqBitLength ne dépasse pas 22.
❄ MinSeqNumber , numéro de séquence minimum, valeur par défaut 5, plage de valeurs [5, MaxSeqNumber], les 5 premiers numéros de séquence par milliseconde correspondent aux nombres 0 à 4 sont des bits réservés, dont 1 à 4 sont des bits réservés correspondant au rappel temporel, 0 est un bit réservé aux nouvelles valeurs manuelles.
❄ MaxSeqNumber , le numéro de séquence maximum, la plage de réglage est [MinSeqNumber, 2^SeqBitLength-1], la valeur par défaut est 0, le numéro de séquence maximum réel est la valeur maximale (2^SeqBitLength-1), s'il n'est pas 0 , il s'agit du véritable numéro de séquence maximum, il n'est généralement pas nécessaire de le définir, sauf si plusieurs machines partagent le WorkerId pour générer des identifiants en segments (dans ce cas, le numéro de séquence minimum doit être correctement défini).
❄ BaseTime , heure de base (également appelée : heure du point de base, heure d'origine, heure de l'époque), a une valeur par défaut (2020), est un horodatage en millisecondes (un entier, .NET est un type DatetTime), sa fonction est : utiliser lors de la génération de l'ID La différence (en millisecondes) entre l'heure système et l'heure de base est utilisée comme horodatage pour générer l'ID. Il n'est généralement pas nécessaire de définir l'heure de base. Si vous estimez que la valeur par défaut est trop ancienne, vous pouvez la réinitialiser. Toutefois, veuillez noter qu'il est préférable de ne pas modifier cette valeur à l'avenir.
La deuxième version prévoit d'ajouter des paramètres :
❄ DataCenterId , ID du centre de données (ID de la salle informatique, 0 par défaut), veuillez vous assurer qu'il est unique au monde.
❄ DataCenterIdBitLength , longueur de l'ID du centre de données (0 par défaut).
❄ TimestampType , type d'horodatage (0 milliseconde, 1 seconde), par défaut 0.
1️⃣ Appel en mode singleton. Cet algorithme utilise un seul thread pour générer des identifiants, et les appels de plusieurs parties s'excluent mutuellement. Au sein de la même instance d'application, l'appelant utilise le multi-threading (ou parallèle) pour appeler cet algorithme, ce qui n'augmentera pas la vitesse de sortie de l'ID.
2️⃣ Spécifiez un WorkerId unique. Le système externe doit garantir l'unicité globale de WorkerId et l'attribuer au paramètre d'entrée de cet algorithme.
3️⃣ Utilisez différents WorkerIds lors du déploiement de plusieurs instances sur une seule machine. Toutes les implémentations ne prennent pas en charge l'unicité simultanée entre processus. Par mesure de sécurité, lors du déploiement de plusieurs instances d'application sur le même hôte, veuillez vous assurer que chaque WorkerId est unique.
4️⃣ Gestion des exceptions. L'algorithme lancera toutes les exceptions et le système externe devra intercepter les exceptions et bien les gérer pour éviter de provoquer un crash système plus important.
5️⃣ Comprenez soigneusement la définition d'IdGeneratorOptions, qui sera utile pour intégrer et utiliser cet algorithme.
6️⃣ Utilisez l'algorithme de dérive de neige. Bien que le code contienne la définition de l'algorithme de flocon de neige traditionnel et que vous puissiez spécifier (Method=2) au point d'entrée pour activer l'algorithme traditionnel, il est toujours recommandé d'utiliser l'algorithme de dérive de flocon de neige (Method=1, la valeur par défaut) , après tout, il a une meilleure extensibilité et des performances plus élevées.
7️⃣ Ne modifiez pas l'algorithme de base. Cet algorithme comporte de nombreux paramètres internes et une logique complexe. Lorsque vous ne maîtrisez pas la logique de base, veuillez ne pas modifier le code de base et l'utiliser dans un environnement de production à moins qu'il n'ait été vérifié par un grand nombre de tests méticuleux et scientifiques.
8️⃣ Les politiques de configuration au sein du domaine d'application sont les mêmes. Lorsque le système fonctionne depuis un certain temps et que le projet doit passer de la spécification par programme de WorkerId à l'enregistrement automatique de WorkerId, veuillez vous assurer que toutes les instances utilisées dans le même domaine d'application adoptent une stratégie de configuration cohérente. Cela ne concerne pas uniquement WorkerId. , mais inclut également d'autres paramètres de configuration.
9️⃣ Gérez bien le temps du serveur. L'algorithme Snowflake repose sur l'heure du système. N'ajustez pas manuellement l'heure du système d'exploitation de manière importante. Si vous devez procéder à des ajustements, n'oubliez pas de vous assurer que l'heure du système au redémarrage du service est supérieure à l'heure à laquelle il a été arrêté pour la dernière fois. (Remarque : de petits changements dans l'heure du système provoqués par une synchronisation ou un rappel de l'heure de classe mondiale ou au niveau du réseau n'ont aucun impact sur cet algorithme)
Les modifications de configuration font référence à l'ajustement des paramètres de fonctionnement (propriétés de l'objet IdGeneratorOptions) après que le système a fonctionné pendant un certain temps. Veuillez noter :
? 1. Le premier principe est le suivant : BaseTime ne peut être qu'ancien (plus éloigné du présent), de sorte que la valeur d'ID générée soit supérieure à la valeur maximale historique, garantissant ainsi qu'il n'y a pas de chevauchement temporel et qu'aucun ID en double n'est généré. [ Il n'est pas recommandé d'ajuster BaseTime une fois le système en cours d'exécution]
? 2. L'augmentation de WorkerIdBitLength ou de SeqBitLength à tout moment est autorisée, mais l'opération de « diminution » doit être utilisée avec prudence, car cela peut faire en sorte que l'ID généré à l'avenir soit le même que l'ancienne configuration. [Autoriser l'augmentation de toute valeur xxxBitLength après le fonctionnement du système]
? 3. Si l'un des WorkerIdBitLength ou SeqBitLength doit être réduit, la condition doit être remplie : la somme des deux nouveaux xxxBitLength doit être supérieure à la somme des anciennes valeurs. [ Il n'est pas recommandé de réduire toute valeur BitLength après l'exécution]
? 4. Les trois règles ci-dessus ne sont pas logiquement contrôlées dans cet algorithme. Les utilisateurs doivent apporter des modifications à la configuration après avoir confirmé que la nouvelle configuration répond aux exigences.
? Le générateur d'ID unique s'appuie sur WorkerId. Lorsque les services métier nécessitent une réplication horizontale et aveugle (expansion automatique), cela nécessite la possibilité d'enregistrer automatiquement un WorkerId unique au monde avant de générer un ID unique.
? Cet algorithme fournit une bibliothèque dynamique open source (implémentée en langage Go), qui peut enregistrer automatiquement WorkerId via Redis dans des environnements de conteneurs tels que k8.
? L'enregistrement de WorkerId via Redis n'est pas le seul moyen. Vous pouvez également développer un service de configuration centralisé. Lorsque chaque service de point de terminaison démarre, le WorkerId unique est obtenu via le service central.
? Bien sûr, si votre service n'a pas besoin de s'étendre automatiquement, vous n'avez pas besoin d'enregistrer automatiquement WorkerId, mais de définir des valeurs globalement uniques pour eux.
? Il existe de nombreuses méthodes, telles que le développement d'un service de génération d'ID centralisé qui génère des ID utilisables pour chaque service de point de terminaison (unique ou par lots).
Lien image : https://github.com/yitter/IdGenerator/blob/master/Tools/AutoRegisterWorkerId/regprocess.jpg
Chemin du code source :/Go/source/regworkerid/reghelper.go
Lien de téléchargement : https://github.com/yitter/IdGenerator/releases/download/v1.3.3/workeridgo_lib_v1.3.3.zip
// 注册一个 WorkerId,会先注销所有本机已注册的记录
// address: Redis连接地址,单机模式示例:127.0.0.1:6379,哨兵/集群模式示例:127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库,示例:1
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster,非哨兵模式传入空字符串即可
// minWorkerId: WorkerId 最小值,示例:30
// maxWorkerId: WorkerId 最大值,示例:63
// lifeTimeSeconds: WorkerId缓存时长(秒,3的倍数),推荐值15
extern GoInt32 RegisterOne(char* server, char* password, GoInt32 db, char* sentinelMasterName, GoInt32 minWorkerId, GoInt32 maxWorkerId, GoInt32 lifeTimeSeconds);
// 注销本机已注册的 WorkerId
extern void UnRegister();
langue | github |
---|---|
?C# | Voir l'exemple |
? | Voir l'exemple |
? Aller | Voir l'exemple |
? Rouiller | Voir l'exemple |
?Python | Voir l'exemple |
?C | Voir l'exemple |
?C (extension PHP) | Voir l'exemple |
? Delphes (Pascal) | Voir l'exemple |
?JavaScript | Voir l'exemple |
?Manuscrit | Voir l'exemple |
?V | Voir l'exemple |
?D | Voir l'exemple |
Adresse open source : https://github.com/yitter/IdGenerator
Groupe QQ : 646049993