Redis
 sql >> Base de données >  >> NoSQL >> Redis

Pourquoi les clés Redis n'expirent-elles pas ?

Edit :Maintenant, avec le code mis à jour, je pense que votre méthodologie est fondamentalement défectueuse en dehors de ce que vous signalez.

La façon dont vous l'avez implémenté nécessite l'exécution de KEYS en production - c'est mauvais. Au fur et à mesure que vous évoluerez, vous provoquerez une charge de blocage système croissante et inutile sur le serveur. Comme chaque document le dit, ne le faites pas utiliser les keys en production. Notez que l'encodage de l'heure d'expiration dans le nom de la clé ne vous donne aucun avantage. Si vous avez fait de cette partie du nom de la clé un horodatage de création, ou même un nombre aléatoire, rien ne changerait. En effet, si vous supprimiez ce bit, rien ne changerait.

Un itinéraire plus sain serait plutôt d'utiliser un nom de clé qui ne dépend pas du temps. L'utilisation de poignées d'expiration qui fonctionnent pour vous. Appelons votre chose à débit limité une "session". Votre nom de clé sans l'horodatage est "l'ID de session". En fixant une expiration de 60 secondes dessus, il ne sera plus disponible à la marque des 61 secondes. Ainsi, vous pouvez incrémenter et comparer en toute sécurité le résultat à votre limite sans avoir besoin de connaître l'heure actuelle ou l'heure d'expiration. Tout ce dont vous avez besoin est un nom de clé statique et un délai d'expiration approprié.

Si vous INCR une clé inexistante, Redis renverra "1", ce qui signifie qu'il a créé la clé et l'a incrémentée en une seule étape/appel. donc en gros la logique est la suivante :

  1. créer un identifiant de "session"
  2. incrémentation du compteur à l'aide de l'ID
  3. comparer le résultat à la limite
    1. si nombre == 1, définissez l'expiration sur 60 s
    2. nombre d'identifiants > limiter, rejeter

L'étape 3.1 est importante. Un décompte de 1 signifie qu'il s'agit d'une nouvelle clé dans Redis et que vous souhaitez y définir votre expiration. Tout le reste signifie que l'expiration devrait déjà avoir été définie. Si vous le définissez en 3.2, vous casserez le processus car il conservera le compteur pendant plus de 60 secondes.

Avec cela, vous n'avez pas besoin d'avoir des noms de clés dynamiques basés sur le temps d'expiration, et donc vous n'avez pas besoin d'utiliser des keys pour savoir s'il existe une "session" existante pour l'objet à débit limité. Cela rend également votre code beaucoup plus simple et prévisible, tout en réduisant les allers-retours vers Redis, ce qui signifie qu'il sera moins chargé sur Redis et plus performant. Quant à savoir comment faire cela avec la bibliothèque cliente que vous utilisez, je ne peux pas le dire car je ne la connais pas très bien. Mais la séquence de base devrait être traduisible car elle est assez basique et simple.

Ce que vous n'avez pas montré, cependant, est quoi que ce soit pour étayer l'affirmation selon laquelle l'expiration ne se produit pas. Tout ce que vous avez fait, c'est montrer que Redis est effectivement informé et définir une expiration. Afin de justifier votre demande, vous devez montrer que la clé n'expire pas. Ce qui signifie que vous devez montrer la récupération de la clé après le délai d'expiration et que le compteur n'a pas été "réinitialisé" en étant recréé après l'expiration. Une façon de voir que l'expiration se produit est d'utiliser les notifications d'espace de clés. Avec cela, vous pourrez voir Redis dire qu'une clé a expiré.

Là où ce processus échouera un peu, c'est si vous faites plusieurs fenêtres pour limiter le débit, ou si vous avez une fenêtre beaucoup plus grande (c'est-à-dire 10 minutes), auquel cas les ensembles triés pourraient être une option plus sensée pour empêcher le chargement frontal des demandes - si on le désire. Mais comme votre exemple est écrit, ce qui précède fonctionnera très bien.