Ключи 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); 
}

почему он не может истекать ключом?

как я уже упоминал, все остальное работает. Я вижу обновление ключа без проблем, если я отслеживаю и могу запросить он.

для протокола, я прочитал:

нет ничего по истечении срока действия на 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 включает в себя:

  1. получение TTL, если ключ существует
  2. после обновления ключа установите срок действия 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 под капотом.