Подтвердить что ты не робот

Уведомление о истечении срока действия ключа в redis python

Я хочу получать уведомления, когда истекает срок действия летучего ключа в моем магазине redis. На веб-сайте redis представлено некоторое описание того, как это можно сделать в http://redis.io/topics/notifications, но мне интересно, можно ли это сделать с помощью python redis api.

После настройки: notify-keyspace-events Ex в моем файле redis.conf

и запустить это как тест:

import redis
import config

client = redis.StrictRedis.from_url(config.REDIS_URI) 
client.set_response_callback('EXPIRE',callback)
client.set('a', 1)
client.expire('a',5)

callback() вызывается только при вызове client.expire('a',5), но не через пять секунд, как ожидалось

4b9b3361

Ответ 1

Неожиданность (без истечения срока действия, когда время жизни для ключа достигает нуля) не привязана к Python, а скорее к пути, у Redis есть ключи.

Документ Redis о сроках истекших событий

Сроки истечения срока действия

Ключи со временем для жизни связаны с Redis двумя способами:

  • Когда ключ получает доступ к команде и, как установлено, истек.
  • Через систему фона, которая ищет устаревшие ключи в фоновом режиме, постепенно, чтобы иметь возможность собирать ключи, которые никогда не доступны.

Истекшие события генерируются при доступе к ключу и истечения срока действия одной из вышеупомянутых систем, в результате чего нет гарантий, что сервер Redis сможет генерировать истекшее событие в момент нажатия клавиши время жизни достигает значения нуля.

Если никакая команда не нацеливает ключ постоянно, и есть много ключей с ассоциированным TTL, может быть значительная задержка между временем, в течение которого ключевое время жизни падает до нуля, и время, в течение которого генерируется истекшее событие.

События с истекшим сроком действия генерируются, когда сервер Redis удаляет ключ, а не когда время на проживание теоретически достигает значения нуля.

Малый тест на консоли

при запуске Redis ($ sudo service redis-server start)

Я запустил одну консоль и подписался:

$ redis-cli
PSUBSCRIBE "__key*__:*"

Затем в другой консоли:

$ redis-cli
> config set notify-keyspace-events AKE

что подписаться на все виды событий

Затем я продолжил эксперименты на этой второй консоли:

> set aaa aaa
> del aaa
> set aaa ex 5
> get aaa

Все действия были видны в подписанной консоли. Только истечение срока действия ключа было несколько секунд задержано, когда-то как раз вовремя.

Заметьте alse, есть тонкие различия в сообщениях, одно сообщение [email protected]__:expire другое [email protected]__:expired.

Пример прослушивателя spy.py

import redis
import time

r = redis.StrictRedis()
pubsub = r.pubsub()
pubsub.psubscribe("*")
for msg in pubsub.listen():
    print time.time(), msg

Этот код регистрирует все существующие каналы по умолчанию redis и печатает все, что публикуется.

Запустите его:

$ python spy.py

а в другой консоли попробуйте установить ключ с истечением срока действия. Вы увидите все события.

Для следующего входа redis-cli.

$ redis-cli
127.0.0.1:6379> set a aha
OK
127.0.0.1:6379> set b bebe ex 3
OK
127.0.0.1:6379> set b bebe ex 3
OK

получаем шпионский вывод:

1401548400.27 {'pattern': None, 'type': 'psubscribe', 'channel': '*', 'data': 1L}
1401548428.36 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:a', 'data': 'set'}
1401548428.36 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'a'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'set'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'b'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expire'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expire', 'data': 'b'}
1401548439.82 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expired'}
1401548439.82 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expired', 'data': 'b'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'set'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'b'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expire'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expire', 'data': 'b'}
1401548487.51 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expired'}
1401548487.51 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expired', 'data': 'b'}