with query pubsub hkeys help cli basics python python-2.7 redis

python - pubsub - redis query



Notificación de caducidad de clave en redis python (1)

Me gustaría recibir una notificación cuando una clave volátil caduque en mi tienda redis. El sitio web de redis proporciona una descripción de cómo se podría lograr esto en http://redis.io/topics/notifications , pero me pregunto si se puede hacer usando la red pyi api de python.

Después de configurar: notify-keyspace-events Ex en mi archivo redis.conf

y ejecutando esto como una prueba:

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() solo recibe una llamada cuando se llama a client.expire(''a'',5) , pero no cinco segundos después como se esperaba


La sorpresa (no se ven eventos de caducidad cuando el tiempo de vida de una clave llega a cero) no está vinculada a Python, sino que, por el contrario, Redis está expirando.

http://redis.io/topics/notifications

Tiempo de eventos vencidos

Redis caduca las claves con un tiempo de vida asociado de dos maneras:

  • Cuando se accede a la clave mediante un comando y se encuentra caducada.
  • A través de un sistema en segundo plano que busca claves caducadas en segundo plano, de forma incremental, para poder recopilar también claves a las que nunca se ha accedido.

Los eventos caducados se generan cuando se accede a una clave y uno de los sistemas anteriores determina que caducó, por lo que no hay garantías de que el servidor Redis pueda generar el evento caducado en el momento en que la clave esté activa. alcanza el valor de cero.

Si ningún comando apunta a la clave constantemente, y hay muchas claves con un TTL asociado, puede haber un retraso significativo entre el momento en que el tiempo de activación de la clave se pone en cero y el momento en que se genera el evento caducado.

Básicamente, los eventos caducados se generan cuando el servidor Redis elimina la clave y no cuando el tiempo de vida teóricamente alcanza el valor de cero.

Pequeño test en consola

cuando se ejecuta Redis ( $ sudo service redis-server start )

Comencé una consola y me he suscrito:

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

Luego, en otra consola:

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

Lo que se suscribirá a todo tipo de eventos.

Luego continué con experimentos en esta segunda consola:

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

Todas las actividades fueron vistas en la consola suscrita. Solo la caducidad de la clave se retrasó unos segundos, en algún momento llegó justo a tiempo.

Tenga en cuenta que, además, hay diferencias sutiles en los mensajes, un mensaje __keyevent@0__:expire otro __keyevent@0__:expired .

spy.py muestra spy.py

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

Este código se registra en todos los canales existentes en redis por defecto e imprime lo que se publica.

Ejecutarlo:

$ python spy.py

y en otra consola intente configurar una clave con un vencimiento. Verás todos los eventos.

Para la siguiente entrada de 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

obtenemos salida de espía:

1401548400.27 {''pattern'': None, ''type'': ''psubscribe'', ''channel'': ''*'', ''data'': 1L} 1401548428.36 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:a'', ''data'': ''set''} 1401548428.36 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:set'', ''data'': ''a''} 1401548436.8 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''set''} 1401548436.8 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:set'', ''data'': ''b''} 1401548436.8 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''expire''} 1401548436.8 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:expire'', ''data'': ''b''} 1401548439.82 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''expired''} 1401548439.82 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:expired'', ''data'': ''b''} 1401548484.46 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''set''} 1401548484.46 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:set'', ''data'': ''b''} 1401548484.46 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''expire''} 1401548484.46 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:expire'', ''data'': ''b''} 1401548487.51 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyspace@0__:b'', ''data'': ''expired''} 1401548487.51 {''pattern'': ''*'', ''type'': ''pmessage'', ''channel'': ''__keyevent@0__:expired'', ''data'': ''b''}