redis keyspace键通知的那些事儿

    在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.


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

发表评论

邮箱地址不会被公开。 必填项已用*标注