Maison  >  Article  >  base de données  >  Comment Redis implémente-t-il les verrous distribués ? Parlons des méthodes de mise en œuvre

Comment Redis implémente-t-il les verrous distribués ? Parlons des méthodes de mise en œuvre

青灯夜游
青灯夜游avant
2021-11-30 19:25:071875parcourir

Comment utiliser Redis pour implémenter des verrous distribués ? L'article suivant vous présentera la méthode d'implémentation des verrous distribués basés sur Redis. J'espère qu'il vous sera utile !

Comment Redis implémente-t-il les verrous distribués ? Parlons des méthodes de mise en œuvre

Dans un système distribué, vous rencontrerez des situations où les ressources partagées par plusieurs nœuds doivent être verrouillées. Dans ce cas, des verrous distribués doivent être utilisés. Les verrous distribués sont généralement stockés dans un système de stockage partagé et peuvent être partagés et accessibles par plusieurs nœuds. [Recommandations associées : Tutoriel vidéo Redis]

L'essence du verrouillage

En termes simples, un verrou peut être représenté par une variable. Par exemple, dans un programme multithread sur une seule machine, le verrouillage d'une certaine ressource peut être représenté par un bit de données. Autrement dit, 0 signifie qu'aucune ressource n'est accessible et 1 signifie que le verrou de ressource a été acquis par un autre thread et n'est pas accessible.

Acquérir et libérer le verrou d'une ressource spécifique consiste essentiellement à obtenir et modifier la valeur de cette variable. Si la valeur est 0, modifiez-la à 1 pour terminer le processus d'acquisition. Si la valeur accédée n'est pas 0, l'acquisition du verrou échoue si le verrou a été acquis auparavant, la valeur de la variable représentant le verrou est modifiée en. 0. En fait, il s’agit de l’opération de déverrouillage.

Dans un scénario distribué, la manière d'implémenter les verrous est la même, sauf que la variable représentant le verrouillage des ressources doit être stockée dans un système de stockage partagé. Ce système de stockage partagé peut être Redis ou tout autre système pouvant fournir un stockage de données.

Implémentation du verrou distribué basé sur Redis

Étape 1 : Implémentation préliminaire de la fonction

Dans le cas de l'utilisation de Redis comme système de stockage partagé, la variable représentant le verrou d'une certaine ressource est une clé dans la paire de valeurs Redis . Si la ressource qui doit être ajoutée avec un verrou distribué s'appelle Resource_a, nous pouvons appeler la clé de la variable de verrouillage de Resource_a dans Redis lock_a.

Par exemple, si le nœud 1 doit acquérir un verrou, il accédera à la valeur de lock_a dans Redis. En supposant que la valeur obtenue est 0, le nœud 1 terminera l'opération de verrouillage après avoir défini cette valeur sur 1. À ce stade, le nœud deux doit également obtenir le verrou de la ressource_a. Il accède à la valeur de lock_a dans Redis et constate que la valeur est 1, indiquant que le verrou a été acquis par un autre nœud et n'a donc pas été libéré. two ne parvient pas à verrouiller la ressource resource_a .

Lorsque le nœud 1 doit libérer le verrou, il lui suffit de définir la valeur de lock_a dans Redis sur 0 pour terminer la libération du verrou. Après cela, les autres nœuds peuvent à nouveau acquérir le verrou de ressource.

Étape 2 : Atomiser l'opération de verrouillage

Dans la description ci-dessus, le verrouillage n'est pas une opération unique, mais comprend plusieurs étapes : lire la variable de verrouillage, juger de la valeur de la variable et modifier la variable de verrouillage. Ces trois opérations doivent être atomiques.

Dans Redis, il existe une commande SETNX, qui est utilisée pour définir la valeur d'une paire clé-valeur. Différente de la commande SET, elle déterminera si la paire clé-valeur existe à l'avance uniquement lorsque la clé spécifiée existe. n'existe pas, il exécutera le réglage de la valeur, sinon rien ne sera exécuté. SETNX signifie "SET si Npas eXist". Son utilisation est la même que SET :

SETNX lock_a 1

De cette façon, lorsque vous devez acquérir un verrou, utilisez la commande SETNX pour définir une valeur pour lock_a. Si le réglage réussit, le verrou est acquis. S'il échoue, le. le verrou n'est pas acquis ; lorsque le verrou doit être libéré, utilisez simplement l'opération DEL pour supprimer la paire clé-valeur.

Cela réalise l'opération atomique d'acquisition et de libération des verrous.

Étape 3 : Empêcher le verrou de ne pas être libéré

La prochaine chose à considérer est qu'une fois que le nœud a acquis le verrou, le verrou n'est jamais libéré en raison d'exceptions du programme et d'autres raisons. Rester Il est détenu par lui et ne peut pas être libéré, et les autres nœuds ne peuvent pas accéder à la ressource.

Afin d'éviter que cette situation ne se produise, nous devons définir le délai d'expiration de la variable de verrouillage. Lorsque la variable de verrouillage expire, nous pouvons redemander le verrouillage, évitant ainsi ce problème.

La commande SETNX n'a ​​pas d'option pour définir le délai d'expiration. Heureusement, Redis fournit l'option NX pour simuler SETNX pour la commande SET. Nous pouvons définir le délai d'expiration comme ceci :

SET lock_a 1 NX PX 10000

La commande ci-dessus signifie que if lock_a. n'existe pas, il existera. Sa valeur est fixée à 1 et expire au bout de 10 secondes.

Étape 4 : Qui verrouille et libère

Le dernier problème est que si le nœud un acquiert le verrou et que, pour une raison quelconque, le nœud deux effectue une opération DEL, alors d'autres nœuds peuvent acquérir à nouveau le verrou.

Afin de résoudre ce problème, nous pouvons modifier le contenu enregistré dans la variable lock. Dans la logique précédente, lorsque nous demandons un verrou, nous déterminons si la variable de verrouillage existe, et cela n'a pas grand-chose à voir avec la valeur qui y est stockée. Nous pouvons donc utiliser cette valeur.

Lors du verrouillage, si la valeur est enregistrée comme identifiant unique de chaque nœud, alors la valeur est jugée avant de libérer le verrou et d'exécuter DEL. Ensuite, vous pouvez d'abord juger si le verrou est ajouté au nœud actuel, oui. Si c'est le cas, puis relâchez-le, réalisant ainsi "celui qui verrouille le verrou le libère".

Dans cette partie, aucune instruction unique ne peut effectuer les opérations de lecture de la variable de verrouillage, de jugement et de suppression. Par conséquent, elle peut être implémentée à l'aide d'un script Lua. Obtenez la valeur de la variable de verrouillage actuelle dans le script et comparez-la avec l'identifiant de nœud donné. Si elle correspond, l'opération de suppression sera effectuée. Sinon, aucune opération ne sera effectuée.

Lorsque vous relâchez le verrou, exécutez simplement le script Lua.

Étape 5 : Implémenter la haute disponibilité

Après avoir amélioré les fonctions, implémentez enfin la haute disponibilité. Si nous utilisons un seul Redis comme système de stockage partagé pour les verrous distribués, alors si ce Redis devient indisponible, toutes les parties liées aux verrous distribués deviendront indisponibles. Cela rend les verrous très fragiles, ce qui est très utile pour des raisons de haute disponibilité.

À ce stade, il est nécessaire de sortir l'algorithme de verrouillage distribué Redlock proposé par Antirez, l'auteur de Redis. En bref, le demandeur du verrou est invité à demander des verrous à plusieurs instances Redis indépendantes. Si l'opération de verrouillage peut être effectuée sur plus de la moitié des instances Redis, le verrou sera acquis avec succès, sinon l'acquisition échouera.

Lors de l'opération de libération du verrou, elle est également considérée comme réussie tant que le script Lua qui supprime avec succès la variable de verrouillage est exécuté sur plus de la moitié des instances.

Pour plus de connaissances sur la programmation, veuillez visiter : Introduction à la programmation ! !

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer