python - redis python中的 key 过期通知

标签 python python-2.7 redis

我希望在我的 redis 存储中的 volatile key 过期时收到通知。 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) 被调用时被调用,但不会像预期的那样晚五秒

最佳答案

意外(当 key 的生存时间达到零时没有看到过期事件)与 Python 无关,而是与 Redis 使 key 过期的方式有关。

Redis doc on Timing of expired events

过期事件的时间

Redis 以两种方式使与生存时间相关联的 key 过期:

  • 当 key 被命令访问并发现已过期时。
  • 通过后台系统逐步在后台查找过期 key ,以便能够收集从未访问过的 key 。

expired events 是在 key 被访问并被上述系统之一发现过期时生成的,因此无法保证 Redis 服务器能够在 key 时生成 expired 事件生存时间达到零。

如果没有命令始终以键为目标,并且有许多键与 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

所有事件都在订阅的控制台中看到。只有 key 过期有时会延迟几秒钟,有时会及时到来。

另外注意,消息有细微差别,一个消息__keyevent@0__:expire另一个__keyevent@0__: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 中的所有现有 channel 并打印发布的任何内容。

运行它:

$ python spy.py

然后在另一个控制台中尝试设置一个过期的 key 。您将看到所有事件。

用于跟随 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

我们得到 spy 输出:

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'}

关于python - redis python中的 key 过期通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23964548/

相关文章:

python - 在 Python 中将 CSV 转换为 UTF-8

python - Selenium 和Python : what is the correct way to define WebElement as property

python - 如何将文件读/写到未知用户目录?

python - 如何处理CreateView中的对象引用

python - 如何在 Python 中将我创建的索引写入文件

facebook - 聚合个人资料提要,如 facebook

java - Redis如何将值存储为json

python - 在 Python 中交错两个 numpy 数组的行

python - 从列表列表中快速选择某些索引的项目

asp.net-mvc - 本地计算机上的 SignalR + Redis