Ключи Redis не истекают - Laravel, Predis
Я использую что Laravel 5.4 С Предиса и последний Redis (или Redis для Windows).
ключи сохраняются без проблем. Поэтому, я сомневаюсь, что это проблема конфигурации.
проблема в том, что они не заканчивающийся. ключ используется повторно до истечения срока его действия...подобно тому, как работает сеанс.
Я создаю ключ один раз, если он не существует. В той же логике я затем установил время истечения.
в контроллере, у меня есть
use IlluminateSupportFacadesRedis;
в одной из функций получить экземпляр соединение:
$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);
}
почему он не может истекать ключом?
как я уже упоминал, все остальное работает. Я вижу обновление ключа без проблем, если я отслеживаю и могу запросить он.
для протокола, я прочитал:
- почему ключи Redis не истекают?
- Laravel flash или сообщения сеанса не истекает [ не поддерживается обновление ]
- мои ключи redis не истекают
нет ничего по истечении срока действия на Laravel документация:
обновление 1
исследование возможной причины, когда установка (обновление) ключа сбрасывает срок действия
обновление 2
использовал рассуждения @for_thestack (в командах REDIS), чтобы придумать решение. Смотрите мой ответ с кодом. Не стесняйтесь upvote @for_thestack:)
3 ответов
какой-то другой процесс может вызвать 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
. Подробности см. В документе.
поскольку @for_stack предоставил мне логику (в Redis commands & logic), я принял его вклад в качестве ответа.
моя проблема заключалась в том, что я этого не знал seting ключ, сбрасывает срок действия. Это, как пояснил @for_stack включает в себя:
- получение TTL, если ключ существует
- после обновления ключа установите срок действия TTL, который я получил от (1)
это означает, что общий TTL не совсем точно. Существует запас миллисекунд или микро секунд, который требуется между временем, когда я получил значение TTL в (1), и временем его обновления.... что меня вполне устраивает!
поэтому для моего сценария 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);
}
отлично работает!
для тех, кто использует Laravel, можно использовать EX param (разрешение истекает) + ttl:
Redis::set($key, $val, 'EX', 35);
в predis u можно использовать то же самое, на самом деле Laravel использует predis под капотом.