Redis键未到期 - Laravel,Predis

use*_*426 8 php redis laravel predis

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

密钥保存没有问题.所以,我怀疑这是一个配置问题.

问题是他们没有到期.密钥将重复使用,直到它过期...类似于会话的工作方式.

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

在控制器中,我有

use Illuminate\Support\Facades\Redis;
Run Code Online (Sandbox Code Playgroud)

在其中一个函数中,获取连接实例:

$redis = Redis::connection();
Run Code Online (Sandbox Code Playgroud)

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

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); 
}
Run Code Online (Sandbox Code Playgroud)

为什么它不会到期钥匙?

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

为了记录,我读过:

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

更新1

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

更新2

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

Art*_*man 8

对于那些使用Laravel的人,可以使用EX param(expire resolution)+ ttl:

Redis::set($key, $val, 'EX', 35);
Run Code Online (Sandbox Code Playgroud)

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


小智 7

如果您使用 Laravel 和 Redis Fassade,您还可以这样做

Redis::setex('yourkey', 120, 'your content'); // 120 seconds
Run Code Online (Sandbox Code Playgroud)

代替

Redis::set('yourkey', 'your content', 'EX', 120);
Run Code Online (Sandbox Code Playgroud)

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


use*_*426 6

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

我的问题是我不知道设置密钥会重置到期时间。所以让它工作,正如@for_stack 所解释的那样涉及:

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

这意味着整体 TTL 不精确。在我获得 (1) 中的 TTL 值到我更新它的时间之间有毫秒或微秒的余量......这对我来说很好!

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

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

//get ttl - time left before expiry
$ttl = $redis->ttl($some_unique_key);
Run Code Online (Sandbox Code Playgroud)

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

//***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); 
}
Run Code Online (Sandbox Code Playgroud)

完美运行!


for*_*ack 5

可能会调用其他一些过程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
Run Code Online (Sandbox Code Playgroud)

为了保留到期时间,在更新键值对时,应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
Run Code Online (Sandbox Code Playgroud)

您可以将这两个命令包装到lua脚本中以使其原子化。并且您还需要注意调用时密钥不存在的情况TTL。有关详细信息,请参见文档。