Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis keys are not expiring - Laravel, Predis

I am using Laravel 5.4, with Predis and the latest Redis (or Redis for Windows).

The keys are being saved without issue. So, I doubt it's a configuration issue.

The problem is that they are not expiring. The key is reused until it expires...similar to how a session works.

I create the key once, if it does not exist. In that same logic I then set the expiration time.

In the Controller, I have

use Illuminate\Support\Facades\Redis;

In one of the functions, Get the connection instance:

$redis = Redis::connection();

Before I create the key, I check the existence (simplified) then create and set 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); 
}

Why could it not be expiring the key?

As I mentioned, everything else works. I see the key updating without issue if I monitor, and can query it.

For the record, I have read:

  • Why Redis keys are not expiring?
  • Laravel flash or session messages not expiring [ not maintained Updated ]
  • my redis keys do not expire

There is nothing on expiration on the Laravel documentation:

  • https://laravel.com/docs/5.4/redis

UPDATE 1

Investigating a possible cause where setting(updating) the key resets the expiry

UPDATE 2

Used @for_thestack's reasoning (in REDIS commands) to come up with the solution. See my answer with the code. Feel free to upvote @for_thestack :)

like image 913
user919426 Avatar asked Apr 21 '17 18:04

user919426


2 Answers

For those who uses Laravel, it is possible to use EX param (expire resolution) + ttl. In below example EX means that TTL is expressed in seconds (see Redis docs: https://redis.io/commands/set). So the result of below will be that $val stored under $key will be removed after 35 seconds.

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

In predis u can use the same, actually Laravel uses predis under the hood.

like image 143
Arthur Kushman Avatar answered Sep 21 '22 19:09

Arthur Kushman


If you're using Laravel and the Redis Fassade, you can also do

Redis::setex('yourkey', 120, 'your content'); // 120 seconds

instead of

Redis::set('yourkey', 'your content', 'EX', 120);

I'm not sure if it was already possible in Laravel 5.4. But definitely with Laravel 8 and Predis 1.1.

like image 31
Sascha Avatar answered Sep 25 '22 19:09

Sascha