Maison  >  Article  >  Java  >  Comment implémenter un verrou distribué à l'aide de Redis

Comment implémenter un verrou distribué à l'aide de Redis

PHPz
PHPzoriginal
2024-08-31 18:31:04714parcourir

je suis bête

Eh bien, chaque fois que nous travaillons dans notre système local, tout fonctionne comme du beurre. C'est pourquoi nous appelons "Pas de meilleur endroit que 127.0.0.1" mais RÉVEILLEZ-VOUS À LA RÉALITÉ

How to implement a Distributed Lock using Redis

Eh bien, les choses ne fonctionnent pas toujours en production comme prévu. Surtout lorsque vous exécutez plusieurs instances de votre application.

How to implement a Distributed Lock using Redis

? Comme vous pouvez le voir, si plusieurs instances de notre application sont en cours d'exécution, disons que notre client demande à marquer un utilisateur comme utilisateur payant dans notre base de données.

  • Le client demandera notre serveur
  • La demande parviendra à notre équilibreur de charge
  • Et l'une des instances recevra la requête et fera une requête d'écriture dans notre base de données

Ça semble bien, n'est-ce pas ? Pas de problème jusqu'à présent, n'est-ce pas.

Eh bien, oui jusqu'à présent, il n'y a pas de problème. Mais que se passe-t-il si nous voulons écrire une logique métier comme :-

  • récupérer l'utilisateur de la base de données
  • vérifiez si l'utilisateur est un utilisateur gratuit ou déjà payé
  • si gratuit, marquez-le comme payant et enregistrez-le dans la base de données
  • si payé, envoyez "Déjà payé" dans la réponse.

⚡️ Comme nous le savons (supposons que nous utilisons MySQL ici) les bases de données MySQL sont conformes à ACID, ce qui signifie que toute requête sera atomique et isolée. ce qui signifie que la requête MySQL sera exécutée de manière atomique, soit elle réussira, soit elle échouera. Mais il ne s'arrêtera pas entre-temps.

? Mais il y a un problème ici. Réfléchissez, réfléchissez....

  • Étape 1 : Nous récupérons l'utilisateur (transaction atomique)
  • Étape 2 : Exécuter une logique métier dans le code
  • Étape 3 : Mise à jour de l'enregistrement MySQL si l'utilisateur n'a pas payé (transaction Atomic)

Que se passera-t-il si à l'étape 2, une demande supplémentaire arrive pour annuler le paiement, puis cette requête s'exécute en premier et marque l'utilisateur comme gratuit, puis l'étape 3 s'exécute et l'utilisateur est marqué comme payant.

?? Hourra, l'utilisateur a eu accès à nos produits sans même payer.

Verrouillage

✅ Voici le sauveur, Locks
How to implement a Distributed Lock using Redis

? Lock est une structure qui permet à un seul thread à la fois d'entrer dans une section critique (bloc de code auquel plusieurs travailleurs ne doivent pas accéder, c'est-à-dire les threads)

Par conséquent, nous acquerrons le verrouillage avant et le libérerons après la fin de l'opération :-

  • Étape 0 : verrouillage try-acquire()
  • Étape 1 : En cas d'acquisition, nous récupérons l'utilisateur (transaction atomique)
  • Étape 2 : Exécuter une logique métier dans le code
  • Étape 3 : Mise à jour de l'enregistrement MySQL si l'utilisateur n'a pas payé (transaction Atomic)
  • Étape 4 : relâcher() le verrou

? Problème

Maintenant, voici le problème : si nous utilisons une structure de données de verrouillage en mémoire ou tout autre verrou basé sur la mémoire, il sera éligible pour une instance pour notre application. qu'en est-il des autres instances exécutant le même code et mis à jour dans la base de données ?

Eh bien, voici le concept de verrouillage distribué

? Verrouillage distribué

How to implement a Distributed Lock using Redis

Ici, le verrou agit comme un service centralisé, où si une instance de notre service acquiert le verrou, les autres ne peuvent pas utiliser la même clé.

QUELLE CLÉ POURRAIT ÊTRE ICI DANS LE SERVICE DE PAIEMENT ?

? Pour un utilisateur effectuant un paiement, la clé pourrait être la combinaison de = "PAYMENT_" + user_id + montant

Et ce sera unique par utilisateur. Et cette clé restera la même en cas d’utilisateur effectuant un paiement ou annulant un paiement. Par conséquent, lorsqu'une action se produit, une autre action ne peut pas avoir lieu car les deux actions tenteront d'acquérir la même clé.

? Qu'est-ce que c'est que la clé, acquérir le verrou, libérer le verrou. Et surtout, comment Redis est-il utilisé ?


? Utiliser Redis pour implémenter le verrouillage distribué

Utilisation d'une seule instance de Redis : -

How to implement a Distributed Lock using Redis

Mais voici les quelques problèmes avec une seule instance Redis :-

  • Une seule instance peut échouer et le verrou acquis peut ne pas être libéré
  • Si deux instances sont utilisées (maître-réplique) lorsqu'un client acquerra le verrouillage sur une instance
  • le maître doit communiquer de la même manière avec la réplique pour se synchroniser. Cette communication elle-même est une communication asynchrone

? Ainsi, si le verrou est acquis sur le maître, et pendant la communication avec le réplica, si le maître tombe en panne avant la synchronisation avec le réplica. La réplique deviendra maître où le verrouillage sur la même clé sera disponible pour acquérir celui qui a été acquis sur le maître plus tôt.

Deux instances de nos services pourront acquérir le verrou sur redis même en ayant deux instances (maître-réplique).

Utilisation de l'algorithme Redlock : -

Acquisition du verrouillage : - Nous allons essayer d'acquérir le verrouillage sur plusieurs instances Redis avec un délai d'expiration du verrouillage
Validation du verrou : - le verrou sera considéré comme acquis si les instances Redis majeures ont obtenu le verrou acquis pour le client
Libération du verrou : - Lors de la libération du verrou, toutes les instances libèrent le verrou

How to implement a Distributed Lock using Redis

Et oui c'est tout.

❤️ Merci pour votre lecture et abonnez-vous à notre newsletter pour plus d'articles de ce type :- https://www.serversidedigest.com/

Pour plus d'informations :-

  • Jedis en Java : - https://redis.io/docs/latest/develop/connect/clients/java/jedis/
  • Client Redis dans Golang : - https://github.com/redis/go-redis

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn