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
Redis keys are not expiring - Laravel, Predis
提问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:
为了记录,我已阅读:
- 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:
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 SET
to 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 SET
with 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 所解释的那样涉及:
- getting the TTL if the key exists
- after updating the key, set the expiration to the TTL that I got from (1)
- 如果密钥存在,则获取 TTL
- 更新密钥后,将过期时间设置为我从 (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!
完美运行!