Maison > développement back-end > Golang > Gérez efficacement les verrous distribués avec Redis : une solution basée sur Go

Gérez efficacement les verrous distribués avec Redis : une solution basée sur Go

DDD
Libérer: 2024-10-21 06:17:02
original
498 Les gens l'ont consulté

Efficiently Manage Distributed Locks with Redis: A Go-Based Solution

Les verrous distribués sont essentiels dans les systèmes où plusieurs processus se disputent les ressources partagées. Qu’il s’agisse d’accès à une base de données ou de modifications de fichiers, il est crucial d’éviter les conditions de concurrence. Dans cet article, je proposerai une implémentation de verrouillage distribué basée sur Redis dans Go, qui peut être utilisée pour synchroniser des tâches sur plusieurs serveurs.

Le principal défi du verrouillage distribué est de garantir que les verrous sont libérés en cas d'échec, d'éviter les blocages et de gérer les conflits. Notre bibliothèque de verrous Redis, intégrée à Go, résout ces problèmes en garantissant que les verrous sont automatiquement libérés et que les demandes en file d'attente sont gérées efficacement.

Cette bibliothèque est construite avec plusieurs fonctionnalités conçues pour rendre le verrouillage distribué simple et fiable :

  • Expiration automatique du verrouillage : les verrous sont automatiquement libérés après un délai d'attente s'ils ne sont pas explicitement déverrouillés, évitant ainsi les blocages.
  • Mécanisme de mise en file d'attente : les demandes concurrentes sont mises en file d'attente, garantissant qu'elles bénéficient d'un accès selon le principe du premier arrivé, premier servi.
  • Abonnement aux événements : la bibliothèque exploite le mécanisme Pub/Sub de Redis pour écouter les événements d'expiration ou de suppression de clé, garantissant ainsi l'efficacité du transfert de verrouillage. Maintenant, commençons par plonger dans les composants et comprendre comment ils fonctionnent à un niveau élevé :

Le rôle de LockManager

Le LockManager joue un rôle clé dans la gestion du cycle de vie des verrous, la gestion de la communication avec Redis et la coordination des demandes de verrouillage. Il est responsable de :

  • Acquisition de verrous : il gère les demandes d'acquisition de verrous sur des clés spécifiques dans Redis, garantissant qu'un seul processus ou thread peut détenir un verrou sur une clé donnée à tout moment.
  • Mise en file d'attente des demandes de verrouillage : si un verrou est déjà détenu par un autre processus, le LockManager ajoute la demande de verrouillage à une file d'attente et attend les notifications Redis indiquant que le verrou a été libéré ou a expiré.
  • Libération des verrous : Il garantit que les verrous sont libérés correctement en vérifiant que le processus tentant de libérer le verrou est celui qui le détient (en fonction de la valeur de verrouillage unique).
  • Écoute des événements d'espace de clés : le gestionnaire s'abonne aux événements d'espace de clés Redis, tels que l'expiration ou la suppression de clés, pour savoir quand les verrous sont libérés et pour avertir les processus en attente.
  • Gestion de plusieurs verrous : LockManager peut gérer plusieurs demandes de verrouillage simultanément, ce qui le rend adapté aux systèmes distribués avec de nombreux processus simultanés. La fonction Lock de LockManager prend un contexte et une clé, tente d'acquérir le verrou, met en file d'attente les requêtes qui ne peuvent pas obtenir immédiatement le verrou, et elle renverra une structure Lock dont nous parlerons dans les sections suivantes.
func (manager *lockManager) Lock(c context.Context, key string, ttl time.Duration) Lock {
    ...
}
Copier après la connexion
Copier après la connexion

La fonction Verrouillage est conçue pour :

  • Générez une valeur unique pour chaque tentative de verrouillage.
  • Assurez-vous que seul le processus/thread qui acquiert le verrou peut le libérer.
  • Utilisez les opérations atomiques de Redis pour acquérir le verrou en toute sécurité.
  • Mettez en file d'attente les demandes de verrouillage et écoutez les événements d'expiration de clé via Redis Pub/Sub.

L'objet Verrouiller

Maintenant, une fois que vous avez obtenu l'objet Lock, vous avez accès aux fonctions Unlock et Wait qui sont conçues pour fonctionner au sein de l'objet. Ces fonctions sont essentielles pour gérer le cycle de vie d'une serrure et gérer le résultat de son acquisition.

Fonction de déverrouillage
La fonction Unlock est chargée de libérer le verrou lorsque le thread ou le processus a terminé avec la ressource. Il garantit que seul le thread ou le processus propriétaire du verrou (c'est-à-dire celui qui détient la valeur de verrouillage correcte) peut le libérer. Voyons comment cela fonctionne :

func (lock *Lock) Unlock() error {
    return lock.manager.releaseLock(lock.key, lock.value)
}
Copier après la connexion

Fonction d'attente
La fonction Attendre permet à l'appelant d'attendre que le résultat de la tentative d'acquisition du verrou soit disponible. Ceci est particulièrement utile dans les cas où un conflit de verrou se produit et où un processus est mis en file d'attente, attendant que le verrou devienne disponible.

func (lock *Lock) Wait() result {
    return <-lock.resultChan
}
Copier après la connexion

Explication :
Attente basée sur le canal : L'objet Lock a un canal resultChan, qui est utilisé pour communiquer le résultat de la tentative d'acquisition du verrou. Lorsque le verrou est acquis (ou échoué), le résultat est envoyé via ce canal. La fonction Attendre se bloque simplement jusqu'à ce qu'un résultat soit disponible.

Exécution non bloquante : lorsqu'un processus tente d'acquérir un verrou à l'aide de Lock(), il n'a pas besoin de bloquer l'intégralité du thread en attendant. Au lieu de cela, il peut appeler Wait(), qui bloquera uniquement jusqu'à ce qu'un résultat soit prêt. Le resultChan permet une communication asynchrone entre la logique de verrouillage et le code appelant, rendant la conception non bloquante.

Objet résultat : La fonction renvoie un objet résultat :

func (manager *lockManager) Lock(c context.Context, key string, ttl time.Duration) Lock {
    ...
}
Copier après la connexion
Copier après la connexion

En résumé, les principales caractéristiques de cette bibliothèque sont sa capacité à gérer une concurrence élevée tout en garantissant que les verrous sont libérés en temps opportun. En utilisant la fonctionnalité TTL de Redis, les verrous sont automatiquement libérés si le processus détenant le verrou échoue.

Les verrous distribués basés sur Redis sont une solution puissante pour gérer les ressources partagées dans les systèmes distribués. Cette bibliothèque Go facilite la mise en œuvre de mécanismes de verrouillage robustes, évolutifs, efficaces et tolérants aux pannes. Consultez le référentiel ici et commencez à créer des systèmes distribués fiables dès aujourd'hui !

Vous souhaitez contribuer ou vous avez des questions ? N'hésitez pas à ouvrir des tickets ou à tirer des requêtes sur le référentiel GitHub.

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!

source:dev.to
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal