redis python中的密钥过期通知

2024-04-20 06:46:20 发布

您现在位置:Python中文网/ 问答频道 /正文

当我的redis存储中的易失性密钥过期时,我希望得到通知。redis网站提供了一些关于如何在http://redis.io/topics/notifications中实现这一点的描述,但我想知道是否可以使用pythonredis api来实现。

在我的redis.conf文件中设置:notify-keyspace-events Ex之后

作为测试运行:

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)时调用,但不会像预期的那样在5秒后调用


Tags: ioimportredisclientconfighttp网站callback
1条回答
网友
1楼 · 发布于 2024-04-20 06:46:20

惊喜(当密钥的生存时间达到零时,没有看到过期事件)并不绑定到Python,而是绑定到Redis正在过期密钥的方式。

Redis doc on Timing of expired events

过期事件的时间安排

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

所有活动都显示在订阅的控制台中。只有密钥过期时间延迟了几秒,而有的只是及时的。

另外,消息也有细微的差别,一条消息__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中的所有现有通道,并打印发布的内容。

运行它:

$ 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': '__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'}

相关问题 更多 >