Manière correcte de déverrouiller le verrouillage Redis

小云云
Libérer: 2023-03-17 21:50:01
original
2822 Les gens l'ont consulté

Redis est un bon ami de PHP. Lors de l'écriture d'affaires en PHP, le concept de verrouillage est parfois utilisé. Une seule personne peut opérer un certain comportement en même temps. À ce stade, nous devons utiliser des verrous. Il existe plusieurs méthodes de verrouillage. PHP ne peut pas utiliser de verrous en mémoire, ni utiliser ZooKeeper pour verrouiller. À l'heure actuelle, nous choisissons généralement Redis comme mécanisme de verrouillage. Cet article partage principalement avec vous la bonne méthode pour déverrouiller Redis, dans l'espoir d'aider tout le monde.

setnx

La structure de données la plus simple verrouillée dans Redis est la chaîne. Dans les premiers jours, setnx était généralement utilisé pour les opérations de verrouillage. Cette commande consiste à définir un val lorsque :lock n'existe pas. Vous vous souviendrez peut-être également d'utiliser expire pour augmenter l'expiration du verrou. Pour déverrouiller l'opération, utilisez le. del commande. Le pseudo code est le suivant :

if (Redis::setnx("my:lock", 1)) {
  Redis::expire("my:lock", 10);
  // ... do something

  Redis::del("my:lock")
}
Copier après la connexion

Il y a en fait un problème ici. Le problème est que s'il y a un crash ou un autre comportement. entre setnx et expire, le verrou ne peut pas être libéré. Une autre solution d'optimisation peut donc consister à stocker l'horodatage dans le verrou. Déterminez la longueur de l’horodatage.

set

Maintenant, il est officiellement recommandé d'utiliser set directement pour implémenter le verrou. Nous pouvons utiliser la commande set pour remplacer setnx, qui ressemble à ce qui suit

if (Redis::set("my:lock", 1, "nx", "ex", 10)) {
  ... do something

  Redis::del("my:lock")
}
Copier après la connexion

Le code ci-dessus définit my:lock sur 1 si et seulement si ceci Lorsque le verrou n'existe pas, le délai d'expiration est fixé à 10 une fois le réglage terminé.

Le mécanisme d'acquisition des verrous est correct, mais le mécanisme de suppression des verrous en utilisant directement del est incorrect. Parce que cela peut conduire à la suppression accidentelle des verrous d'autres personnes.

Par exemple, j'ai verrouillé ce verrou pendant 10 secondes, mais le temps de traitement était supérieur à 10 secondes. Au bout de 10 secondes, le verrou a automatiquement expiré, a été retiré par d'autres et a été reverrouillé. Puis à ce moment-là, lorsque j'appelle à nouveau Redis::del, il supprimera le verrou créé par d'autres.

Le responsable a également des suggestions pour déverrouiller les commandes. Il est recommandé d'utiliser le script lua, d'effectuer d'abord get, puis d'exécuter del

Le programme devient :

$token = rand(1, 100000);

function lock() {
  return Redis::set("my:lock", $token, "nx", "ex", 10);
}

function unlock() {
  $script = `
if redis.call("get",KEYS[1]) == ARGV[1]
then
  return redis.call("del",KEYS[1])
else
  return 0
end  
  `
  return Redis::eval($script, "my:lock", $token)
}

if (lock()) {
  // do something

  unlock();
}
Copier après la connexion

Le jeton ici est un nombre aléatoire Lors du verrouillage, ce jeton est stocké dans my:lock dans redis. Lors du déverrouillage, récupérez d'abord le jeton dans le verrou. it, Les jetons sont cohérents, ce qui signifie que le verrou a été défini par moi auparavant, sinon cela signifie que le verrou a expiré et a été défini par quelqu'un d'autre, et je ne devrais effectuer aucune opération dessus.

Donc : n'utilisez plus setnx, utilisez set directement pour l'implémentation du verrouillage.

Recommandations associées :

php Utiliser le verrouillage Redis pour limiter la classe d'accès simultané

php Exemple d'utilisation du verrouillage Redis pour limiter la classe d'accès simultané

Résumé des méthodes courantes d'exploitation de Redis en PHP

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!

Étiquettes associées:
source:php.cn
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