Cet article est un article miroir de traduction automatique, veuillez cliquer ici pour accéder à l’article original.

Vue: 10939|Répondre: 1

Plusieurs façons d’utiliser les verrous distribués (redis, zookeeper, base de données)

[Copié le lien]
Publié sur 30/08/2018 15:04:32 | | | |
Q : Un serveur de service, une base de données, opération : interroger le solde actuel de l’utilisateur, déduire 3 % du solde actuel comme frais de traitement

synchronisé
serrure
Verrouillage de dB

Q : Deux serveurs de service, une base de données, fonctionnement : interroger le solde actuel de l’utilisateur, déduire 3 % du solde actuel comme frais de gestion
Verrous distribués

Quel type de serrure distribuée avons-nous besoin ?
Elle peut garantir que dans un cluster d’applications distribuées, la même méthode ne puisse être exécutée que par un seul thread sur une machine en même temps.

Si cette serrure est une serrure rentrée (éviter les blocages)

Cette serrure est la meilleure pour être une serrure de blocage (réfléchissez à ce que vous souhaitez selon les besoins de votre entreprise)

Cette serrure est idéale pour être une serrure équitable (réfléchissez à ce type selon les besoins professionnels)

Des fonctions de verrouillage d’acquisition et de libération sont très disponibles

Les performances des verrous d’acquisition et de libération sont meilleures

1. Verrous distribués basés sur des bases de données

Verrous distribués basés sur des implémentations basées sur des tables

Lorsque nous voulons verrouiller une méthode, exécutons le SQL suivant :
insérer dans méthodLock(method_name,desc) valeurs ('method_name','desc')
Parce que nous avons imposé une contrainte d’unicité sur le method_name, si plusieurs requêtes sont soumises à la base de données simultanément, celle-ci garantira qu’une seule opération peut réussir, alors nous pouvons supposer que le thread qui a obtenu avec succès la méthode se verrouille et exécute le contenu du corps de la méthode.

Lorsque la méthode est exécutée, si vous souhaitez libérer le verrou, vous devez exécuter le SQL suivant :
delete from methodLock où method_name ='method_name'

Cette implémentation simple ci-dessus présente les problèmes suivants :

  • Ce verrouillage dépend de la disponibilité de la base de données, qui est un point unique et rendra le système métier indisponible une fois la base de données bloquée.
  • Ce verrou n’a pas de délai d’expiration, et une fois l’opération de déverrouillage échouée, l’enregistrement de verrouillage restera dans la base de données et les autres threads ne pourront plus obtenir le verrou.
  • Ce verrou ne peut être non bloquant que parce que l’opération d’insertion des données signalera directement une erreur une fois l’insertion échouée. Les threads qui n’acquièrent pas de verrous n’entreront pas dans la file d’attente et devront déclencher à nouveau l’opération d’acquisition de verrou pour obtenir à nouveau le verrou.
  • Le verrou n’est pas réentrant, et le même filetage ne peut pas le récupérer tant qu’il n’est pas libéré. Parce que les données existent déjà.
  • Cette serrure est injuste, et tous les fils qui attendent la serrure se disputent par chance.


Bien sûr, nous pouvons aussi résoudre les problèmes ci-dessus d’autres manières.

  • La base de données est-elle un point unique ? Construisez deux bases de données, et les données seront synchronisées dans les deux sens. Une fois raccroché, passez rapidement à la bibliothèque de sauvegarde.
  • Pas de délai d’expiration ? Fais simplement une tâche programmée pour nettoyer les données de délai dans la base de données à intervalles réguliers.
  • Non-blocage ? Faites une boucle d’un certain temps jusqu’à ce que l’insert réussisse, puis vous revenez avec succès.
  • Non-réentrant ? Ajoutez un champ à la table de la base de données pour enregistrer les informations hôte et thread de la machine qui reçoit actuellement le verrou, puis la prochaine fois que vous obtenez le verrou, interrogez d’abord la base de données, si les informations hôte et thread de la machine actuelle sont trouvées dans la base de données, vous pouvez directement lui attribuer le verrou.
  • Injuste ? Créer une autre table intermédiaire pour enregistrer tous les threads en attente du verrou, les trier selon le temps de création, et seul le premier créé est autorisé à acquérir le verrou


Serrures distribuées basées sur des verrous exclusifs

En plus d’ajouter et supprimer des enregistrements dans la table de données, les verrous distribués peuvent également être implémentés à l’aide des verrous fournis avec les données.

Nous utilisons aussi la table de base de données que nous venons de créer. Les verrous distribués peuvent être implémentés via des verrous exclusifs sur des bases de données. Le moteur InnoDB basé sur MySQL peut utiliser les méthodes suivantes pour implémenter des opérations de verrouillage :

Si vous ajoutez pour mise à jour après l’instruction de requête, la base de données ajoutera un verrouillage exclusif à la table de la base de données pendant le processus de requête. Lorsqu’un verrou exclusif est ajouté à un enregistrement, les autres threads ne peuvent plus ajouter de verrou exclusif à l’enregistrement sur cette ligne.

On peut penser que le thread qui obtient le verrou exclusif peut obtenir le verrou distribué, et lorsque le verrou est obtenu, la logique métier de la méthode peut être exécutée, puis déverrouillée via les méthodes suivantes :

déverrouillage public de l’inconnu(){ connexion.commit() ; }

via connection.commit() ; opération pour libérer la serrure.

Cette méthode peut résoudre efficacement les problèmes mentionnés ci-dessus, concernant l’impossibilité de libérer la serrure et de bloquer la serrure.

Bloquer les serrures ? L’instruction for update revient immédiatement après une exécution réussie et reste bloquée jusqu’à ce qu’elle réussisse.

Service coupé après la serrure, impossible de le libérer ? De cette façon, la base de données libère le verrou d’elle-même après la panne du service.

Cependant, cela ne résout toujours pas directement le problème du point unique de base de données, de la réentrance et du verrouillage équitable.

Pour résumer la manière d’utiliser la base de données pour implémenter des verrous distribués, tous deux reposant sur une table dans la base de données, l’un consiste à déterminer s’il existe un verrou par l’existence des enregistrements dans la table, et l’autre à implémenter des verrous distribués via le verrou exclusif de la base de données.

Avantages du verrouillage distribué des bases de données

Directement avec l’aide de la base de données, c’est facile à comprendre.

Inconvénients de la mise en œuvre de verrous distribués dans les bases de données

Il y aura divers problèmes, et la solution globale deviendra de plus en plus complexe dans le processus de résolution du problème.

L’exploitation de la base de données nécessite une certaine surcharge, et des problèmes de performance doivent être pris en compte.

2. Verrous distribués basés sur le cache

Comparé à la solution de verrouillage distribué basée sur une base de données, l’implémentation basée sur le cache sera plus performante.

Il existe actuellement de nombreux produits de mise en cache matures, notamment Redis, memcached, etc. Ici, prenons Redis comme exemple pour analyser le schéma d’utilisation du cache afin d’implémenter des verrous distribués.

Il existe de nombreux articles connexes sur Internet concernant la mise en œuvre de verrous distribués basés sur Redis, et la principale méthode d’imploration consiste à utiliser la méthode Jedis.setNX.

Il existe également plusieurs problèmes avec la mise en œuvre ci-dessus :

1. Problème d’un seul point.

2. Ce verrou n’a pas de délai d’expiration ; une fois l’opération de déverrouillage échouée, cela fera que l’enregistrement du verrou sera en redis en permanence, et les autres threads ne pourront plus obtenir le verrou.

3. Ce verrou ne peut être que non bloquant, et il reviendra directement quel que soit le succès ou l’échec.

4. Ce cadenas n’est pas réentrant, après qu’un fil ait obtenu le cadenas, il ne peut plus obtenir le cadenas avant de le relâcher, car la clé utilisée existe déjà dans le redis. les opérations setNX ne peuvent plus être exécutées.

5. Ce verrouillage est injuste, tous les threads en attente lancent les opérations setNX en même temps, et les threads chanceux peuvent obtenir le verrouillage.

Bien sûr, il existe aussi des moyens de le résoudre.

  • De nos jours, les services de mise en cache grand public supportent le déploiement par cluster pour résoudre des problèmes ponctuels via le clustering.
  • Pas de délai d’expiration ? La méthode setExpire de redis prend en charge le temps d’expiration entrant, et les données sont automatiquement supprimées une fois ce temps atteint.
  • Non-blocage ? tout en étant exécuté à plusieurs reprises.
  • N’est-il pas possible de rentrer ? Après qu’un thread ait acquis le verrou, enregistrez les informations hôtes actuelles et les informations du thread, et vérifiez si vous êtes le propriétaire du verrou actuel avant de l’obtenir la prochaine fois.
  • Injuste ? Mettez tous les fils en attente dans une file d’attente avant qu’un fil n’acquiert un verrou, puis acquérez le verrou selon le principe du premier entrant, premier sorti.


La politique de synchronisation du cluster redis prend du temps, et il est possible que le thread A obtienne un verrouillage après avoir défini NX avec succès, mais cette valeur n’a pas été mise à jour sur le serveur où le thread B exécute setNX, ce qui causera des problèmes de concurrence.

Salvatore Sanfilippo, l’auteur de redis, a proposé l’algorithme Redlock, qui implémente une gestion distribuée de verrous (DLM) plus sécurisée et fiable qu’un seul nœud.

L’algorithme Redlock suppose qu’il existe N nœuds redis indépendants les uns des autres, généralement réglés à N=5, et que ces N nœuds fonctionnent sur différentes machines pour maintenir leur indépendance physique.

Les étapes de l’algorithme sont les suivantes :

1. Le client obtient le temps courant en millisecondes.
2. Le client tente d’obtenir le verrou de N nœuds (chaque nœud obtient le verrou de la même manière que le verrouillage de cache mentionné précédemment), et N nœuds obtiennent le verrou avec la même clé et la même valeur. Le client doit définir le délai d’attente d’accès à l’interface, et le délai d’attente de l’interface doit être bien inférieur au temps d’attente du verrouillage, par exemple, le temps de libération automatique du verrou est de 10 secondes, puis le délai d’attente de l’interface est fixé à environ 5 à 50 ms. Cela permet de mettre un temps d’attente dès que possible lors de l’accès à un nœud Redis après qu’il soit tombé, et réduit l’utilisation normale du verrou.
3. Le client calcule combien de temps il faut pour obtenir le verrou, en soustrayant le temps obtenu à l’étape 1 par le temps courant, ce n’est que lorsque le client obtient plus de 3 nœuds du verrou, et que le temps d’acquisition du verrou est inférieur au temps d’expiration du verrou, que le client obtient le verrou distribué.
4. Le temps que le client a pour acquérir le verrou correspond au temps d’expiration défini moins le temps passé à obtenir le verrou calculé à l’étape 3.
5. Si le client ne parvient pas à obtenir le verrou, celui-ci supprimera tous les verrous à son tour.
En utilisant l’algorithme Redlock, il est garanti que le service de verrouillage distribué peut toujours fonctionner lors de la fermeture jusqu’à 2 nœuds, ce qui améliore considérablement la disponibilité par rapport aux précédents verrous de base de données et verrouillage cache.

Cependant, un expert distribué a rédigé un article intitulé « Comment faire le verrouillage distribué » remettant en question la justesse du Redlock.

L’expert a mentionné qu’il y a deux aspects à prendre en compte lorsqu’on considère les serrures distribuées : la performance et la justesse.

Si vous utilisez un verrou distribué haute performance et que la correction n’est pas requise, alors utiliser un verrou cache est suffisant.

Si vous utilisez une serrure distribuée très fiable, vous devez alors prendre en compte des questions strictes de fiabilité. Redlock, en revanche, ne répond pas à la justesse. Pourquoi pas? Les experts énuent plusieurs aspects.

De nos jours, de nombreux langages de programmation utilisent des machines virtuelles avec des fonctions GC, en Full GC, le programme s’arrête de traiter le GC, parfois Full GC prend beaucoup de temps, et même le programme a quelques minutes de latence, l’article cite l’exemple de HBase, parfois HBase GC pendant quelques minutes, ce qui provoque l’expiration du bail. Par exemple, dans la figure ci-dessous, le client 1 obtient un verrou et s’apprête à traiter une ressource partagée, et lorsqu’il s’apprête à traiter une ressource partagée, la Full GC se produit jusqu’à l’expiration du verrou. De cette façon, le client 2 obtient à nouveau le verrou et commence à travailler sur la ressource partagée. Lorsque le client 2 est en traitement, le client 1 complète la GC complète et commence à traiter les ressources partagées, de sorte que les deux clients traitent les ressources partagées.



Les experts ont donné une solution, comme montré dans la figure ci-dessous, cela ressemble à MVCC : amener un jeton au verrou, le jeton est le concept de version : à chaque fois que le verrouillage d’opération est terminé, le jeton sera ajouté 1, apportez le jeton lors du traitement des ressources partagées, seule la version spécifiée du jeton peut gérer la ressource partagée.



Ensuite, l’expert a également dit que l’algorithme repose sur l’heure locale, et que Redis s’appuie sur la méthode getTimeOfDay pour obtenir l’heure au lieu de l’horloge monotone lors de la gestion de l’expiration des clés, ce qui entraîne également des inexactitudes temporelles. Par exemple, dans un scénario, deux clients 1 et client 2 ont 5 nœuds redis (A, B, C, D et E).

1. Le client 1 acquiert avec succès le verrou de A, B et C, et obtient le délai d’attente du réseau de verrous de D et E.
2. L’horloge du nœud C est imprécise, ce qui provoque le délai d’attente du verrou.
3. le client 2 obtient avec succès le verrou de C, D et E, et obtient le délai d’attente du réseau de verrous de A et B.
4. De cette façon, les clients 1 et 2 obtiennent tous deux un verrouillage.
Pour résumer les deux points que les experts avancent sur l’indisponibilité de Redlock :

1. La GC et d’autres scénarios peuvent survenir à tout moment, provoquant un verrouillage par le client, et le délai d’expiration du traitement provoque l’obtention du verrou par un autre client. Les experts ont également proposé une solution pour l’utilisation de jetons auto-incrémentifs.
2. L’algorithme repose sur l’heure locale, et l’horloge sera imprécise, ce qui entraînera deux verrous à deux clients en même temps.
Par conséquent, la conclusion donnée par les experts est que Redlock ne peut fonctionner normalement que dans la plage de délai de réseau borné, d’interruption de programme bornée et d’erreur d’horloge bornée, mais les limites de ces trois scénarios ne peuvent être confirmées, les experts ne recommandent donc pas d’utiliser Redlock. Pour les scénarios avec des exigences élevées en correction, les experts recommandent Zookeeper, qui sera abordé plus tard en utilisant Zookeeper comme un cadenas distribué.

Réponse de l’auteur de Redis

L’auteur de Redis a répondu en écrivant un blog après avoir vu l’article de l’expert. L’auteur a poliment remercié l’expert, puis a exprimé son désaccord avec son point de vue.

J’ai demandé une analyse dans la spécification Redlock originale ici :http://redis.io/topics/distlock.Alors merci Martin. Cependant, je ne suis pas d’accord avec l’analyse.


La discussion de l’auteur de REDIS sur l’utilisation des jetons pour résoudre le problème du délai de verrouillage peut être résumée en cinq points suivants :

Point 1, l’utilisation des verrous distribués consiste généralement à ne pas avoir d’autre moyen de contrôler les ressources partagées, les experts utilisent des jetons pour assurer le traitement des ressources partagées, alors il n’y a pas besoin de verrous distribués.
Point 2 : Pour la génération de jetons, afin d’assurer la fiabilité des jetons obtenus par différents clients, le service qui génère les jetons a toujours besoin de verrous distribués pour garantir la fiabilité du service.
Point 3, pour la façon dont les experts disent que les jetons auto-incrémentants sont que l’auteur de Redis estime que c’est totalement inutile, chaque client peut générer un UUID unique en tant que jeton, et définir la ressource partagée à un état que seul le client avec l’uuid peut gérer, de sorte que les autres clients ne peuvent pas traiter la ressource partagée tant que le client qui obtient le verrou ne le libère pas.
Comme montré dans la figure ci-dessus, si le client du jeton 34 envoie GC pendant le processus d’écriture et provoque une expiration du verrouillage, un autre client peut obtenir le verrou du jeton 35 et recommencer à écrire, ce qui entraîne un conflit de verrou. Par conséquent, l’ordre des jetons ne peut pas être combiné avec des ressources partagées.
Point 5, l’auteur de Redis estime que dans la plupart des scénarios, les verrous distribués sont utilisés pour gérer les problèmes de mise à jour dans des scénarios non transactionnels. L’auteur doit vouloir dire qu’il existe des scénarios où il est difficile de combiner des jetons pour gérer les ressources partagées, donc il faut compter sur des verrous pour bloquer et traiter les ressources.
Un autre problème d’horloge dont parlent les experts est que les auteurs de Redis donnent aussi une explication. Si le temps nécessaire pour acquérir le cadenas est trop long et dépasse le délai d’expiration par défaut du cadenas, alors le client ne peut pas obtenir le cadenas à ce moment-là, et aucun exemple n’est proposé par des experts.

Sentiments personnels

Le premier problème que je résume est qu’après qu’un client obtient un verrou distribué, celui-ci peut être libéré après un délai d’attente pendant le traitement du client. Auparavant, lorsqu’on parlait du délai d’attente fixé par le verrouillage de la base de données de 2 minutes, si une tâche occupe un verrouillage d’ordre plus de 2 minutes, alors l’autre centre de négociation peut obtenir ce verrouillage d’ordre, afin que les deux centres de négociation puissent traiter le même ordre en même temps. Dans des circonstances normales, la tâche est traitée en quelques secondes, mais parfois, le délai d’attente fixé par la reliance d’une requête RPC est trop long, et s’il y a plusieurs demandes de délai dans une tâche, il est donc probable que le temps de déverrouillage automatique soit dépassé. Si nous écrivons en Java, il peut y avoir un Full GC au milieu, donc après que le verrou soit déverrouillé après le délai de verrouillage, le client ne peut pas le percevoir, ce qui est très grave. Je ne pense pas que ce soit un problème lié au verrou lui-même, tant que tout verrou distribué mentionné ci-dessus a les caractéristiques de libération du timeout, un tel problème se produira. Si vous utilisez la fonction de délai de verrouillage, le client doit définir la durée d’attente du verrouillage et agir en conséquence, au lieu de continuer à traiter la ressource partagée. L’algorithme de Redlock renvoie le temps de verrouillage que le client peut occuper après que le client a acquis le verrou, et le client doit traiter ce temps pour arrêter la tâche après ce temps.

Le deuxième problème est que les experts distribués ne comprennent pas Redlock. Une caractéristique clé de Redlock est que le temps d’acquisition du verrou correspond au temps total pendant lequel le verrou passe par défaut au temps d’expiration, moins le temps nécessaire pour l’obtenir, de sorte que le temps nécessaire au client pour traiter est relatif, quel que soit le temps local du cadenas.

De ce point de vue, la justesse de Redlock est tout à fait garantie. Une analyse attentive de Redlock, comparée à la redis d’un nœud, la principale caractéristique offerte par Redlock est une fiabilité accrue, ce qui est une caractéristique importante dans certains scénarios. Mais je pense que Redlock a dépensé trop d’argent pour atteindre la fiabilité.

  • Premièrement, 5 nœuds doivent être déployés pour rendre Redlock plus fiable.
  • Ensuite, il faut demander 5 nœuds pour obtenir le verrouillage, et via la méthode Future, vous pouvez d’abord demander à 5 nœuds en même temps, puis obtenir le résultat de la réponse, ce qui peut raccourcir le temps de réponse, mais cela prend quand même plus de temps qu’un verrouillage Redis à nœud unique.
  • Alors, comme plus de 3 des 5 nœuds doivent être obtenus, il peut y avoir un conflit de verrou, c’est-à-dire que tout le monde a obtenu 1 ou 2 verrous, et par conséquent, personne ne peut obtenir le verrou, ce problème, l’auteur de Redis emprunte l’essence de l’algorithme du radeau, par la collision à un moment aléatoire, le temps de conflit peut être grandement réduit, mais ce problème ne peut pas être très bien évité, surtout lorsque le verrou est acquis pour la première fois, ce qui augmente le coût en temps pour acquérir le verrou.
  • Si 2 des 5 nœuds sont hors service, la disponibilité du verrou sera fortement réduite ; tout d’abord, vous devez attendre que les résultats de ces deux nœuds tombés expirent avant de revenir, et il n’y a que 3 nœuds, et le client doit obtenir les verrous des 3 nœuds pour avoir le verrou, ce qui est également plus difficile.
  • S’il existe une partition réseau, il se peut que le client ne puisse jamais obtenir le verrou.


Après avoir analysé tant de raisons, je pense que le point le plus critique du problème de Redlock est que Redlock exige que les clients assurent la cohérence des écritures, et que les 5 nœuds du backend sont complètement indépendants, et que tous les clients doivent gérer ces 5 nœuds. S’il y a un leader parmi 5 nœuds, le client peut synchroniser les données du leader tant que le client obtient le verrouillage du leader, de sorte qu’il n’y aura pas de problèmes tels que le partitionnement, les délais d’expiration ou les conflits. Par conséquent, afin d’assurer la justesse des verrous distribués, je pense que l’utilisation d’un service de coordination distribué avec une forte cohérence peut mieux résoudre le problème.

La question se pose à nouveau : combien de temps dois-je définir le délai d’expiration ? La façon de régler le temps d’invalidation est trop courte, et le verrou est automatiquement libéré avant l’exécution de la méthode, ce qui entraîne des problèmes de concurrence. Si cela prend trop de temps, les autres fils qui obtiennent le verrouillage devront peut-être attendre longtemps.

Ce problème existe également avec l’utilisation de bases de données pour implémenter des verrous distribués.

L’approche courante actuelle à ce problème consiste à fixer un court délai d’extinction pour chaque verrou obtenu, puis à lancer un thread pour rafraîchir le temps d’extinction à chaque fois qu’il est sur le point d’atteindre ce temps. Terminez ce fil en même temps que la libération du verrou. Par exemple, redisson, le composant officiel distribué de redis, utilise cette solution.

Avantages de l’utilisation de la mise en cache pour implémenter des verrous distribués
Bonne performance.

Inconvénients de l’utilisation de la mise en cache pour implémenter des verrous distribués
La mise en œuvre est trop responsable, il y a trop de facteurs à prendre en compte.

Verrous distribués basés sur l’implémentation de Zookeeper

Des verrous distribués basés sur des nœuds temporaires ordonnés par Zookeeper.

L’idée générale est que lorsque chaque client verrouille une méthode, un nœud ordonné instantané unique est généré dans le répertoire du nœud spécifié correspondant à la méthode sur zookeeper. La façon de déterminer si vous voulez obtenir un verrou est simple : il suffit de déterminer celui avec le plus petit numéro de série dans le nœud ordonné. Lorsque le verrou est relâché, il suffit de supprimer le nœud instantané. En même temps, cela peut éviter le problème des blocages causés par des interruptions de service qui ne peuvent pas être libérées.

Voyons si Zookeeper peut résoudre les problèmes mentionnés plus tôt.

  • La serrure ne se déverrouille pas ? Utiliser Zookeeper peut résoudre efficacement le problème des verrous qui ne sont pas libérés, car lors de la création d’un verrou, le client crée un nœud temporaire dans ZK, et une fois que le client obtient le verrou et le bloque soudainement (la connexion de session est coupée), le nœud temporaire sera automatiquement supprimé. D’autres clients peuvent retrouver la serrure.
  • Serrures non bloquantes ? Une fois que le nœud change, Zookeeper notifiera le client, qui pourra vérifier si le nœud créé est le plus petit nombre ordinal parmi tous les nœuds.
  • Impossible de rentrer ? Lorsque le client crée un nœud, il écrit directement les informations hôtes et thread du client actuel au nœud, et la prochaine fois que vous souhaitez obtenir le verrouillage, vous pouvez le comparer avec les données du plus petit nœud actuel. Si les informations sont les mêmes que les vôtres, vous pouvez alors obtenir directement le verrou, et s’il est différent, créer un nœud séquentiel temporaire pour participer à la file d’attente.


La question se pose à nouveau : nous savons que Zookeeper doit être déployé en clusters, y aura-t-il des problèmes de synchronisation des données comme dans les clusters Redis ?

Zookeeper est un composant distribué qui garantit une cohérence faible, c’est-à-dire une cohérence éventuelle.

Zookeeper utilise un protocole de synchronisation des données appelé Quorum Based Protocol. S’il y a N serveurs Zookeeper dans le cluster Zookeeper (N est généralement impair, 3 peuvent assurer la fiabilité des données et avoir de hautes performances en lecture et écriture, et 5 ont le meilleur équilibre entre fiabilité des données et performance de lecture et d’écriture), alors une opération d’écriture de l’utilisateur est d’abord synchronisée avec N/2 + 1 serveurs, puis renvoyée à l’utilisateur, l’invitant à écrire avec succès. Le protocole de synchronisation des données basé sur le Quorum Based Protocol détermine la cohérence de la puissance que Zookeeper peut supporter.

Dans un environnement distribué, le stockage de données qui assure une forte cohérence est pratiquement inexistant, et il nécessite que tous les nœuds soient mis à jour de manière synchrone lors de la mise à jour des données d’un seul nœud. Cette stratégie de synchronisation apparaît dans la base de données de réplication synchrone maître-esclave. Cependant, cette stratégie de synchronisation a un impact trop important sur les performances d’écriture et est rarement observée en pratique. Comme Zookeeper écrit N/2+1 nœuds de façon synchrone, et que N/2 nœuds ne sont pas mis à jour de façon synchrone, Zookeeper n’est pas fortement cohérent.

L’opération de mise à jour des données de l’utilisateur ne garantit pas que les lectures ultérieures liront la valeur mise à jour, mais montrera finalement une cohérence. Sacrifier la cohérence ne signifie pas ignorer complètement la cohérence des données, sinon les données sont chaotiques, donc peu importe la disponibilité du système ou la qualité de la distribution, elle n’a aucune valeur. Sacrifier la cohérence, c’est simplement qu’une forte cohérence dans les bases de données relationnelles n’est plus nécessaire, mais tant que le système peut atteindre la cohérence à terme.

Une question à point unique ? L’utilisation de Zookeeper peut résoudre efficacement un problème ponctuel unique, ZK est déployée en clusters, tant que plus de la moitié des machines du cluster survivent, le service peut être fourni au monde extérieur.

Des problèmes d’équité ? L’utilisation de Zookeeper peut résoudre le problème des verrous équitables, les nœuds temporaires créés par le client dans ZK sont ordonnés, et à chaque fois que le verrou est libéré, ZK peut notifier le plus petit nœud pour obtenir le verrou, garantissant ainsi l’équité.

La question se pose à nouveau : nous savons que Zookeeper doit être déployé en clusters, y aura-t-il des problèmes de synchronisation des données comme dans les clusters Redis ?

Zookeeper est un composant distribué qui garantit une cohérence faible, c’est-à-dire une cohérence éventuelle.

Zookeeper utilise un protocole de synchronisation des données appelé Quorum Based Protocol. S’il y a N serveurs Zookeeper dans le cluster Zookeeper (N est généralement impair, 3 peuvent assurer la fiabilité des données et avoir de hautes performances en lecture et écriture, et 5 ont le meilleur équilibre entre fiabilité des données et performance de lecture et d’écriture), alors une opération d’écriture de l’utilisateur est d’abord synchronisée avec N/2 + 1 serveurs, puis renvoyée à l’utilisateur, l’invitant à écrire avec succès. Le protocole de synchronisation des données basé sur le Quorum Based Protocol détermine la cohérence de la puissance que Zookeeper peut supporter.

Dans un environnement distribué, le stockage de données qui assure une forte cohérence est pratiquement inexistant, et il nécessite que tous les nœuds soient mis à jour de manière synchrone lors de la mise à jour des données d’un seul nœud. Cette stratégie de synchronisation apparaît dans la base de données de réplication synchrone maître-esclave. Cependant, cette stratégie de synchronisation a un impact trop important sur les performances d’écriture et est rarement observée en pratique. Comme Zookeeper écrit N/2+1 nœuds de façon synchrone, et que N/2 nœuds ne sont pas mis à jour de façon synchrone, Zookeeper n’est pas fortement cohérent.

L’opération de mise à jour des données de l’utilisateur ne garantit pas que les lectures ultérieures liront la valeur mise à jour, mais montrera finalement une cohérence. Sacrifier la cohérence ne signifie pas ignorer complètement la cohérence des données, sinon les données sont chaotiques, donc peu importe la disponibilité du système ou la qualité de la distribution, elle n’a aucune valeur. Sacrifier la cohérence, c’est simplement qu’une forte cohérence dans les bases de données relationnelles n’est plus nécessaire, mais tant que le système peut atteindre la cohérence à terme.

Le fait que Zookeeper respecte la cohérence causale dépend de la manière dont le client est programmé.

Pratiques qui ne satisfont pas à la cohérence causale

  • Le processus A écrit une donnée sur le /z de Zookeeper et la retourne avec succès
  • Le processus A informe le processus B que A a modifié les données de /z
  • B lit les données du /z de Zookeeper
  • Puisque le serveur du Gardien du Zoo connecté à B n’a peut-être pas été mis à jour avec les données écrites de A, alors B ne pourra pas lire les données écrites de A


Pratiques qui respectent la cohérence causale

  • Le Processus B écoute les changements de données en /z sur Zookeeper
  • Le processus A écrit une donnée sur le /z de Zookeeper, et avant qu’elle ne revienne avec succès, Zookeeper doit appeler l’auditeur enregistré sur /z, et le leader informera B du changement de données
  • Après que la méthode de réponse à l’événement du processus B ait été répondue, elle prend les données modifiées, donc B pourra certainement obtenir la valeur modifiée
  • La cohérence causale ici fait référence à la cohérence causale entre le leader et B, c’est-à-dire que le leader notifie les données d’un changement


Le second mécanisme d’écoute d’événements est aussi la méthode qui doit être utilisée pour programmer correctement Zookeeper, donc Zookeeper doit respecter la cohérence causale

Ainsi, lorsque nous implémentons des verrous distribués basés sur Zookeeper, nous devrions utiliser la pratique de satisfaire la cohérence causale, c’est-à-dire que les threads en attente du verrou écoutent les changements dans le verrou de Zookeeper, et lorsque le verrou est libéré, Zookeeper notifiera le thread en attente qui remplit les conditions de verrouillage équitables.

Vous pouvez utiliser directement le client de bibliothèque tierce Zookeeper, qui encapsule un service de verrouillage à réentrants.

Les verrous distribués implémentés avec ZK semblent correspondre exactement à ce que nous attendions d’un verrou distribué au début de cet article. Cependant, ce n’est pas le cas, et le verrou distribué implémenté par Zookeeper présente en réalité un inconvénient, à savoir que les performances peuvent ne pas être aussi élevées que celles du service de mise en cache. Car à chaque fois lors de la création et de la libération d’un verrou, des nœuds instantanés doivent être créés et détruits dynamiquement pour réaliser la fonction de verrouillage. La création et la suppression de nœuds dans ZK ne peuvent être effectuées que via le serveur leader, puis les données sont partagées avec toutes les machines suiveuses.

Avantages d’utiliser Zookeeper pour implémenter des verrous distribués
Résoudre efficacement les problèmes de point unique, les problèmes de non-rentrée, les problèmes de non-blocage et les échecs de déverrouillage. C’est relativement simple à mettre en œuvre.

Inconvénients d’utiliser Zookeeper pour implémenter des verrous distribués
Les performances ne sont pas aussi bonnes que celles d’utiliser le cache pour implémenter des verrous distribués. Une compréhension des principes de ZK est requise.

Comparaison des trois options

Du point de vue de la facilité de compréhension (du bas au haut)
Base de données > Cache > Zookeeper

Du point de vue de la complexité de l’implémentation (de faible à élevé)
Cache> Zookeeper > bases de données

D’un point de vue performance (du haut au bas)
Mise en cache > Zookeeper >= base de données

D’un point de vue fiabilité (du haut au bas)
Cache> Zookeeper > bases de données





Précédent:Différence entre @Bean de printemps et @Service d’annotations
Prochain:Tutoriel vidéo pour apprendre le langage C à partir de zéro
 Propriétaire| Publié sur 22/09/2020 17:34:33 |
[Combat réel]. NET Core implémente des verrous distribués basés sur Redis
https://www.itsvse.com/thread-9391-1-1.html

Implémentation du verrou distribué .net/c# Zookeeper [Code source]
https://www.itsvse.com/thread-4651-1-1.html

Démenti:
Tous les logiciels, supports de programmation ou articles publiés par Code Farmer Network sont uniquement destinés à l’apprentissage et à la recherche ; Le contenu ci-dessus ne doit pas être utilisé à des fins commerciales ou illégales, sinon les utilisateurs assumeront toutes les conséquences. Les informations sur ce site proviennent d’Internet, et les litiges de droits d’auteur n’ont rien à voir avec ce site. Vous devez supprimer complètement le contenu ci-dessus de votre ordinateur dans les 24 heures suivant le téléchargement. Si vous aimez le programme, merci de soutenir un logiciel authentique, d’acheter l’immatriculation et d’obtenir de meilleurs services authentiques. En cas d’infraction, veuillez nous contacter par e-mail.

Mail To:help@itsvse.com