Redis键未到期 - Laravel,Predis

时间:2017-04-21 18:29:04

标签: php laravel redis predis

我正在使用Laravel 5.4Predis和最新Redis(或Redis for Windows)。

正在保存密钥而不会出现问题。所以,我怀疑这是一个配置问题。

问题在于它们没有到期。 密钥会在到期之前重复使用...类似于会话的工作方式。

如果密钥不存在,我会创建一次密钥。在同样的逻辑中,我然后设置到期时间。

在控制器中,我有

use Illuminate\Support\Facades\Redis;

在其中一个功能中,获取连接实例

$redis = Redis::connection();

在创建密钥之前,我检查存在(简化)然后创建并设置到期。

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); 
}

为什么它不会过期?

正如我所提到的,其他一切都有效。如果我监控,我会看到密钥更新没有问题,并且可以查询它。

为了记录,我读过:

Laravel文档到期时没有任何内容:

更新1

调查设置(更新)密钥的可能原因会重置到期日

更新2

使用@ for_thestack的推理(在REDIS命令中)来提出解决方案。用代码查看我的回答。随意upvote @for_thestack:)

4 个答案:

答案 0 :(得分:5)

对于那些使用Laravel的人,可以使用EX param(过期解析)+ ttl:

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

在预测中你可以使用相同的,实际上Laravel在引擎盖下使用了predis。

答案 1 :(得分:4)

其他一些进程可能会调用SET来更新键值对,在这种情况下,过期将被删除。

// 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

为了保持过期,当您更新键值对时,应使用过期参数调用SET

// 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

您可以将两个命令包装到lua脚本中以使其成为原子。而且,当您致电TTL时,您还需要注意密钥不存在的情况。有关详细信息,请参阅文档。

答案 2 :(得分:3)

由于@for_stack为我提供了逻辑(在REDIS命令和逻辑中),我接受了他的贡献作为答案。

我的问题是我不知道设置键,重置到期日。因此,正如@for_stack所解释的那样,使其工作包括:

  1. 如果密钥存在,则获取TTL
  2. 更新密钥后,将到期时间设置为我从(1)
  3. 获得的TTL

    这意味着整体TTL不准确。在我获得(1)中的TTL值到更新它的时间之间需要毫秒或微秒的余量....这对我没问题!

    因此,对于我的Laravel(PHP),Predis场景,我执行以下操作:

    在某个相关点,代码中的更高位置:

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

    然后,无论我在哪里更新值,我都会在设置值后设置到期时间。 创建密钥的逻辑(在我的问题中)保持正确且不变。

    //***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); 
    }
    

    完美无缺!

答案 3 :(得分:1)

如果你使用 Laravel 和 Redis Fassade,你也可以这样做

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

代替

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

我不确定 Laravel 5.4 中是否已经可以实现。 但绝对是 Laravel 8 和 Predis 1.1。