我希望在我的redis商店中挥发性密钥到期时收到通知。 redis网站提供了如何在http://redis.io/topics/notifications中实现这一目标的一些描述,但我想知道是否可以使用python redis 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)
时被调用,但不会在预期后五秒钟被调用
答案 0 :(得分:32)
令人惊讶的是(当密钥的生存时间达到零时没有看到过期事件)没有绑定到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'}