幽沉谢世事,俯默窥唐虞。这篇文章主要讲述Redis发布订阅原理与实践相关的知识,希望能为你提供帮助。
简述Redis提供了发布订阅功能,可以用于消息的传输, 通过 PUBLISH 、 SUBSCRIBE 和 PSUBSCRIBE 等命令实现发布和订阅功能
分类频道的发布订阅
基于Channel的消息事件,这一类消息和Redis中存储的Keys没有太多关联,这类消息事件是独立使用(PUBLISH,SUBSCRIBE)
实现原理Redis将所有频道的订阅关系都保存在服务器状态的 pubsub_channels 字典,字典的键是某个被订阅的频道,而对应值则是一个链表,链表里记录了所有订阅这个频道的客户端。
struct redisServer
//...
// 保存所有频道订阅关系
dict *pubsub_channels; /* Map channels to list of subscribed clients */
//...
一个pubsub_channels字典示例如下:
client-1、client-2三个客户端正在订阅 “redis” 频道
客户端 client-3 正在订阅 “mysql” 频道
订阅频道命令
SUBSCRIBE redis [mysql …]
频道有订阅者
在pubsub_channels字典中已存在该频道,此时server端会将订阅者客户端添加到该频道的链表末端
频道无订阅者
pubsub_channels字典中无此频道,在字典中创建频道,并此客户端放至该频道链表的第一位
应用实例1、订阅普通频道或多频道
127.0.0.1:6379> SUBSCRIBE redis mysql
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redis"
3) (integer) 1
1) "subscribe"
2) "mysql"
3) (integer) 2
1) "message"
2) "redis"
3) "1"
1) "message"
2) "mysql"
3) "1"
模式的发布订阅
消息事件主要是对Redis中存储的Keys信息的变化事件进行通知,可以用来向订阅者通知Redis中符合订阅条件的Keys的各种事件(需要redist开启notify-keyspace-events参数,PSUBSCRIBE订阅),还可以通过Channel订阅消息,模式订阅psubscribe的Channel订阅和subscribe命令类似。
实现原理Redis将所有模式的订阅关系都保存在服务器状态的 pubsub_patterns 链表,链表的每个节点都包含着一个 pubsub Pattern 结构,这个结构的 pattern 属性记录了被订阅的模式,而 client 属性则记录了订阅模式的客户端。
struct redisServer
//...
// 保存所有模式订阅关系
list *pubsub_patterns; /* A list of pubsub_patterns */
dict *pubsub_patterns_dict; /* A dict of pubsub_patterns */
int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an
xor of NOTIFY_... flags. */
//...
一个pubsub_patterns链表示例:
客户端 client-7 正在订阅模式 "redis*"
客户端 client-8 正在订阅模式 "mysql*"
订阅模式命令
PSUBSCRIBE pattern [pattern …]
【Redis发布订阅原理与实践】当客户端执行PSUBSCRIBE。redis server端会做如下操作
1、新建一个 pubsubPattern结果,将结构的 pattern 属性设置为被订阅的模式,client 属性设置为订阅模式的客户端;
2、将pubsubPattern结构添加到 pubsub_patterns 链表的尾部
应用举例
- 订阅模糊频道
127.0.0.1:6379> PSUBSCRIBE redis* mysql*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redis*"
3) (integer) 1
1) "psubscribe"
2) "mysql*"
3) (integer) 2
1) "pmessage"
2) "mysql*"
3) "mysql2"
4) "1"
1) "pmessage"
2) "redis*"
3) "redis2"
4) "1"
- 订阅Redis key事件
K:启用keyspace键空间通知,客户端可以使用__keyspace@< db> __为前缀的格式使用订阅功能。
E:启用keyevent键事件通知,客户端可以使用__keyevent@< db> __为前缀的格式使用订阅功能。
g:监控一般性事件,包括但不限于对del,expire,rename事件的监控。
$:启用对字符串格式(即一般K-V结构)命令的监控。
l:启用对List数据结构命令的监控。
s:启用对Set数据结构命令的监控。
h:启用对Hash数据结构命令的监控。
z:启用对ZSet数据结构命令的监控。
x:启用对过期事件的监控。
e:启用对驱逐事件的监控,当某个键因maxmemory达到设置时,使用策略进行内存清理,会产生这个事件。
A:g$lshzxe通配符组合的别名,也就是说”AKE”这样的通配符组合,意味着所有事件。
举例说明
// 监控任何数据格式的所有事件,包括键空间通知和键事件通知
notify-keyspace-events "AKE"
// 只监控字符串结构的所有事件,包括键空间通知和键事件通知
notify-keyspace-events "g$KExe"
// 只监控所有键事件通知
notify-keyspace-events "AE"
// 只监控Hash数据解构的键空间通知
notify-keyspace-events "ghKxe"
// 只监控Set数据结构的键事件通知
notify-keyspace-events "gsExe"
(1)订阅0号数据库中,所有的键变化事件,进行键空间通知
psubscribe __keyspace@0__:*
(1)订阅0号数据库中,所有的键变化事件,进行键事件通知
psubscribe __keysevent@0__:*
(2) 订阅0号数据库,test_redis_模糊键变化事件,进行键空间通知和键事件通知
psubscribe __key*@0__:test_redis_*
(3)订阅0号数据库中,模糊的键变化事件,进行键空间通知
psubscribe __key*@0__:*
相关命令
- 查看所有的频道:PUBSUB CHANNELS
- 查询订阅者的数量:PUBSUB NUMSUB
- 查询服务器被订阅者的数量:PUBSUB NUMPAT
- Redis无法对消息持久化存储,一旦消息被发送,如果没有订阅者接收,那么消息就会丢失
- Redis没有提供消息传输保障,当客户端连接超时等情况发生时,消息不会被重新发送给客户端
- 订阅过期key时,只有当key被真正清理才会被发送道订阅通道,ttl 为0 不会被发送(这种情况一般发生在大批量的key过期集中在一个时间,redis负载相对较高高)
- 消息位广播模式,订阅的客户端都会收到相同的消息,客户端会有重复消费问题
推荐阅读
- #yyds干货盘点#在element-ui中使用dialog的时候只有遮罩,看不见内容的问题
- Mac系统安装ELK环境踩坑记录
- 一文掌握oracle19c之离线情况下命令行安装和建库(下)- 本文干货满满,记得收藏哈
- ??苏州程序大白解析Linux 中的虚拟网络接口??《??记得收藏??》
- uni-app技术分享| uni-app常见问题
- 一种简单的OpenHarmony开发环境搭建
- Jmeter目录结构及常用元件
- 智汀云盘-开发指南android(文件/文件夹上传下载:gomobile)
- 缓存加速——NoSQL之Redis配置与优化