Redis 密钥不会过期 - Laravel、Predis

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43549670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:50:14  来源:igfitidea点击:

Redis keys are not expiring - Laravel, Predis

phplaravelredispredis

提问by user919426

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

我正在使用Laravel 5.4以及Predis和最新的Redis(或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:

为了记录,我已阅读:

There is nothing on expiration on the Laravel documentation:

Laravel 文档中没有任何关于到期的内容:

UPDATE 1

更新 1

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

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

UPDATE 2

更新 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 :)

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

采纳答案by for_stack

Some other process might call SETto update the key-value pair, in this case, the expiration will be removed.

其他一些进程可能会调用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

In order to keep the expiration, when you update the key-value pair, you should call SETwith expiration parameters.

为了保持过期,当您更新键值对时,您应该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

You can wrap the two commands into a lua script to make it atomic. And you also need to take care of the case that key doesn't exist when you call TTL. See the document for details.

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

回答by Arthur Kushman

For those who uses Laravel, it is possible to use EX param (expire resolution) + ttl:

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

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

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

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

回答by user919426

Since @for_stack provided me with the logic(in REDIS commands & logic), I accepted his contribution as the answer.

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

My problem was that I did not know that seting the key, resets the expiry. So making it work, as explained by @for_stack involves:

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

  1. getting the TTL if the key exists
  2. after updating the key, set the expiration to the TTL that I got from (1)
  1. 如果密钥存在,则获取 TTL
  2. 更新密钥后,将过期时间设置为我从 (1) 获得的 TTL

It means that the overall TTL is not precise. There is a margin of milli or micro seconds that it takes between the time I got the TTL value in (1) to the time I update it.... which is fine by me!

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

So for my Laravel(PHP), Predis scenario, I do the following:

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

At some relevant point, higher up in the code:

在一些相关的点,在代码的更高处:

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

Then wherever I have to update the value, I set the expiry after setting the value. The logic for creating the key(in my question) remains correct and unchanged.

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

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

Works perfectly!

完美运行!