web-dev-qa-db-fra.com

Les clés Redis n'expirent pas - Laravel, Predis

J'utilise Laravel 5.4 , avec Predis et la dernière Redis (ou Redis pour Windows ).

Les clés sont enregistrées sans problème. Donc, je doute que ce soit un problème de configuration.

Le problème est qu'ils n'expirent pas. La clé est réutilisée jusqu'à son expiration ... similaire au fonctionnement d'une session.

Je crée la clé une fois, si elle n'existe pas. Dans cette même logique, j'ai ensuite réglé le délai d'expiration.

Dans le contrôleur, j'ai

use Illuminate\Support\Facades\Redis;

Dans l'une des fonctions, Obtenez l'instance de connexion :

$redis = Redis::connection();

Avant de créer la clé, je vérifie l'existence (simplifiée) puis crée et règle l'expiration.

if(!$redis->exists($some_unique_key))
{
   //set the key
   $redis->set($some_unique_key, 'Some Value'));
   //set the expiration
   //I understand this means expire in 60s.
   $redis->expire($some_unique_key,60); 
}

Pourquoi ne pourrait-il pas expirer la clé?

Comme je l'ai mentionné, tout le reste fonctionne. Je vois la mise à jour des clés sans problème si je surveille et je peux l'interroger.

Pour mémoire, j'ai lu:

Il n'y a rien à l'expiration dans la documentation Laravel:

MISE À JOUR 1

Recherche d'une cause possible où le réglage (la mise à jour) de la clé réinitialise l'expiration

MISE À JOUR 2

Utilisé le raisonnement de @ for_thestack (dans les commandes REDIS) pour trouver la solution. Voir ma réponse avec le code. N'hésitez pas à voter pour @th_stack :)

10
user919426

Un autre processus peut appeler SET pour mettre à jour la paire clé-valeur, dans ce cas, l'expiration sera supprimée.

// set expiration
EXPIRE key expiration_in_seconds
// update key-value pair with no expiration
SET key new_value
// now, expiration has been reset, and the key won't be expired any more

Afin de conserver l'expiration, lorsque vous mettez à jour la paire clé-valeur, vous devez appeler SET avec les paramètres d'expiration.

// get TTL, i.e. how much time left before the key will be expired
TTL key
// update with expiration parameter
SET key new_value EX ttl

Vous pouvez envelopper les deux commandes dans un script lua pour le rendre atomique. Et vous devez également prendre soin du cas où cette clé n'existe pas lorsque vous appelez TTL. Voir le document pour plus de détails.

6
for_stack

Pour ceux qui utilisent Laravel, il est possible d'utiliser EX param (résolution expirée) + ttl:

Redis::set($key, $val, 'EX', 35);

Dans predis, vous pouvez utiliser la même chose, en fait Laravel utilise des predis sous le capot.

9
Arthur Kushman

Puisque @for_stack m'a fourni la logique (dans les commandes et la logique REDIS), j'ai accepté sa contribution comme réponse.

Mon problème était que je ne savais pas que set ing la clé, réinitialise l'expiration. Donc, pour que cela fonctionne, comme expliqué par @for_stack, vous devez:

  1. obtenir le TTL si la clé existe
  2. après la mise à jour de la clé, définissez l'expiration sur TTL que j'ai obtenu de (1)

Cela signifie que la valeur globale TTL n'est pas précise. Il y a une marge de milli ou de micro-secondes entre le moment où j'ai obtenu la valeur TTL dans ( 1) au moment où je le mets à jour .... ce qui me convient!

Donc pour mon scénario Laravel (PHP), Predis, je fais ce qui suit:

À un moment pertinent, plus haut dans le code:

//get ttl - time left before expiry
$ttl = $redis->ttl($some_unique_key);

Ensuite, partout où je dois mettre à jour la valeur, je règle l'expiration après avoir défini la valeur. La logique de création de la clé (dans ma question) reste correcte et inchangée.

//***note that I am UPDATING a key. Checking if it exists then I update
if($redis->exists($some_unique_key))
{
   //set/up the key
   $redis->set($some_unique_key, 'Some New, Updated, Value'));

   //Do some work   

   //set the expiration with the TTL value from (1)
   $redis->expire($some_unique_key,$ttl); 
}

Fonctionne parfaitement!

4
user919426