携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
Redis发布-订阅( pub/sub)是一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。发布-订阅模式是观察者模式的一种,观察者通过监听消息发布者的状态,来通知消息订阅者,达到系统通知的效果。
因为Redis实现了Reactor模型,Redis客户端可以订阅任意数量的频道,因此多个工作进程(Linux中线程称为LWP,Light Weight Process轻量级进程)大大提升了线程处理的效率。
另外,Redis因为实现了Reactor模型,因此通过发布-订阅模型中的管道技术:客户端可以在服务端未响应时,继续向服务端发送请求,并最终一次性读取所有服务端的响应。并且可以针对一些读写的指令顺序进行优化,避免重复读写等。
订阅-发布模型消息关系图:
第一个为消息发送者,第二个为订阅的频道,第三个为消息订阅者。
下图展示了频道channel1,以及订阅这三个频道的客户端——client2、client5和client1之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
Redis 发布订阅命令
这些命令被广泛用于构建即时通信应用,比如网络聊天室(chatroom)和实时广播、实时提醒等。
下表列出了 redis 发布订阅常用命令(psubscribe、pubsub、publish、punsubscribe、subscribe、unsubscribe):
| 序号 | 命令及描述 |
|---|---|
| 1 | PSUBSCRIBE [pattern [pattern ...]]订阅一个或多个符合给定模式的频道。 |
| 2 | PUBSUB subcommand [argument [argument ...]]查看订阅与发布系统状态。 |
| 3 | PUBLISH channel message 将信息发送到指定的频道。 |
| 4 | PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。 |
| 5 | [SUBSCRIBE channel [channel ...]]](www.runoob.com/redis/pub-s…) 订阅给定的一个或多个频道的信息。 |
| 6 | UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。 |
测试
订阅端:
127.0.0.1:6379> subscribe deepinsea # 订阅一个频道 deepinsea
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "deepinsea"
3) (integer) 1
1) "message" # 消息(通知类型)
2) "deepinsea" # 哪个频道的消息
3) "hello,deepinsea" # 消息的具体内容
1) "message"
2) "deepinsea"
3) "hello,redis"
发送端:
127.0.0.1:6379> publish deepinsea "hello,deepinsea" # 发布者发布消息到频道
(integer) 1
127.0.0.1:6379> publish deepinsea "hello,redis" # 发布者发布消息到频道
(integer) 1
127.0.0.1:6379>
原理
Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅机制的底层实现,籍此加深对Redis的理解。
Redis通过publish、subscribe和psubcribe等命令实现发布和订阅功能。
通过subscribe命令订阅某频道后,redis-server里维护了一个字典,字典的键即时一个个channel,而字典的值则是一个链表,链表中保存了所有订阅这个channel的客户端。subscribe命令的关键,就是将客户端添加到给定channel的订阅链表中。
通过publish命令向订阅者发送消息,redis-server会使用给定的频道作为键,在它所维护的channel字典中查找记录了这个订阅这个频道所有客户端的链表,遍历这个链表,将消息发布给所有的订阅者。
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及订阅,当一个key值上进行了消息发布后,所有订阅它对的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
使用场景
1、实时消息系统;
2、实时聊天(频道当做聊天室,将消息回显给所有人即可);
3、订阅、关注系统。
稍微复杂的场景,为了消息的可靠性和准确性,我们使用消息中间件即可。
下一篇,我们对Redis持久化的两种方式RDB和AOF进行学习,应该就到了进阶部分的内容了:
欢迎点赞关注评论,感谢观看ヾ(◍°∇°◍)ノ゙