Maison  >  Article  >  base de données  >  Plusieurs façons d'implémenter le limiteur de vitesse dans Redis

Plusieurs façons d'implémenter le limiteur de vitesse dans Redis

尚
avant
2020-03-28 09:29:412566parcourir

Plusieurs façons d'implémenter le limiteur de vitesse dans Redis

Redis propose plusieurs façons d'implémenter le limiteur de vitesse.

GET + INCR + EXPIRE

Obtenez d'abord la valeur actuelle de la clé Si elle ne dépasse pas la limite, exécutez INCR et augmentez-la de 1. Si la clé le fait. n'existe pas, utilisez la clé d'initialisation de la transaction Redis et le délai d'expiration.

(Recommandé : Tutoriel vidéo Redis)

Pseudo code :

count = redis.GET(key)
if redis return nil {
  redis.MULTI
  	redis.INCR(key)
  	redis.EXPIRE(key, expire_time)
  redis.EXEC
  count = 1
}
if count > limit {
  return 超出限制
} else {
  redis.INCR(key)
}

Problèmes en cas de concurrence élevée :

Si 10 à la en même temps Si un programme simultané exécute GET et renvoie zéro, alors ces 10 programmes simultanés exécuteront des transactions redis pour augmenter la clé de un, mais la valeur de comptage de chaque programme est 1. Si la valeur définie par limite est inférieure à 10, alors la le programme réellement exécuté sera La limite a été dépassée. Si redis est vérifié à nouveau après l'exécution de la transaction et affecté au comptage, alors chaque programme peut renvoyer 10, donc aucun programme ne peut continuer à s'exécuter.

Lorsque la clé existe déjà, la logique de GET d'abord puis d'INCR peut également faire dépasser la limite du nombre de programmes réellement exécutés.

INCR + EXPIRE

INCR d'abord, si la valeur est 1, cela signifie que la clé vient d'être définie, puis exécutez EXPIRE

Pseudo code :

count = redis.INCR(key)
if count == 1 {
  redis.EXPIRE(key, expire_time)
}
if count > limit {
  return 超出限制
}

À utiliser avec prudence

Si le programme se bloque après INCR et EXPIRE n'est pas exécuté, alors la clé n'aura pas de délai d'expiration. L'impact spécifique dépend des besoins.

lua script

local current
current = redis.call("incr",KEYS[1])
if tonumber(current) == 1 then
    redis.call("expire",KEYS[1],1)
end

Pour plus de connaissances sur Redis, veuillez faire attention à la colonne Tutoriel d'introduction à 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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer