在Redis2.8.0版本的时候,推出 Keyspace Notifications future。 Keyspace Notifications 此特性允许客户端可以以 订阅/发布(Sub/Pub)模式,接收那些对数据库中的键和值有影响的操作事件。这些操作事件具体来说,就是 hash , del, expire , set , lpop 等。
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新. http://xiaorui.cc/?p=4123
那么你可能会问,redis keyspace 到底有啥用处? 简单说,对于我个人主要关注keyspace几个扩展场景:
1. 类似审计或者监控的场景.
2. 通过expire来实现不可靠的定时器.
3. 借助expire来实现不可靠的注册发现.
为什么说是不可靠的实现?
首先Redis Pub/Sub 是一种并不可靠地消息机制,他不会做信息的存储,只是在线转发,那么肯定也没有ack确认机制,另外只有订阅段监听时才会转发!!! 所以Keyspace Notification 也不是可靠地通知系统,如果你的系统需要很好的可靠性,那么Keyspace Notification可能并不是一种很好的选择。
默认情况下,Redis 并不会开启Keyspace Notification, 我们可以通过修改redis.conf的notify-keyspace-events 或者使用CONFIG SET命令来开启该功能,设置参数,来开启全部或者部分通知, 以下是设置参数详细说明列表:
# xiaorui.cc
K Keyspace events, published with __keyspace@<db>__ prefix.
E Keyevent events, published with __keyevent@<db>__ prefix.
g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
String commands
l List commands
s Set commands
h Hash commands
z Sorted set commands
x Expired events (events generated every time a key expires)
e Evicted events (events generated when a key is evicted for maxmemory)
A Alias for glshzxe, so that the "AKE" string means all the events.
通过config set指令来在线keyspace配置.
开启所有的事件 redis-cli config set notify-keyspace-events KEA 开启keyspace Events redis-cli config set notify-keyspace-events KA 开启keyspace 所有List 操作的 Events redis-cli config set notify-keyspace-events Kl
接收到的事件的类型只有两种: keyspace 和 keyevent。
前者为事件的具体操作,后者为事件影响的键名。比如我们操作一个kv , set blog xiaorui.cc
127.0.0.1:6379> CONFIG SET notify-keyspace-events KEA OK 127.0.0.1:6379> set blog http://xiaorui.cc OK 127.0.0.1:6379>
数据库0会发布以下两个信息
1) "pmessage" 2) "__key*@0__:*" 3) "__keyspace@0__:blog" 4) "set" 1) "pmessage" 2) "__key*@0__:*" 3) "__keyevent@0__:set" 4) "blog"
第一条信息的通道名称有 keyspace 前缀,是 keyspace 类型,内容为具体操作 set 。第二条信息的通道名称有 keyevent 前缀,是 keyevent 类型,内容为影响的键名 blog 。
keyspace事件返回的结果里只有触发的key,没有value值 !!! 如果你想看到value,就需要调用redis monitor了
再来看看 redis expire 触发样例:
1) "pmessage" 2) "__key*@0__:*" 3) "__keyspace@0__:blog" 4) "expired" 1) "pmessage" 2) "__key*@0__:*" 3) "__keyevent@0__:expired" 4) "blog"
需要注意下redis expire的实现:
Redis expire事件,因为Redis expire的Lazy机制,并不是在key的TTL时间归零时,就触发删除,而是当有主动请求或者是Redis定时的清理时,才会真正的从Redis cache中删除。而redis expire的事件也只有当真正在删除时,才会触发。这和key值的到期时间是有时间差的。
redis keyspace的实现原理也是比较简单,主要是在 notifyKeyspaceEvent 函数里。 根据 server.notify_keyspace_events 的值,决定应该发送那些通知。 通过 pubsubPublishMessage 函数,将事件从频道中发送出去。 pubsubPublishMessage 函数是 PUBLISH 命令的实现函数, 调用它相当于调用 PUBLISH 命令。 关于 redis keyspace的具体代码实现,可以看看黄建宏的文章
http://note.huangz.me/storage/redis_code_analysis/keyspace-notification.html …
END.