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") }
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") }
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(); }
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!