Redis入门到入坑14——发布订阅

Redis 入门到入坑14------发布订阅

Redis发布/订阅模式

简介

Redis发布订阅(Pub/Sub)是一种消息传递模式,它允许发送消息的进程(发布者)向特定的接收消息的进程(订阅者)传递消息。在Redis中,发布者和订阅者都可以通过频道(channel)来发送和接收消息。

  • 发布者:发布者向指定的频道发送消息。发布者可以发送各种类型的消息,例如字符串、哈希、列表等。

  • 订阅者:订阅者订阅一个或多个频道,并接收这些频道中的消息。订阅者可以同时订阅多个频道,以接收不同类型的信息。

  • 频道:频道是发布者和订阅者之间的通信媒介。发布者将消息发送到特定的频道,订阅者从这些频道接收消息。

  • 持久化:Redis的发布订阅是持久化的,即使订阅者在消息发送时不在线,当订阅者再次连接时,它可以获取所有未接收的消息

下图展示了频道与订阅者的关系以及新消息发布时的流程

Redis 发布/订阅模式的工作流程

  1. 发布者向一个或多个频道发送消息。
  2. Redis将消息存储在内部缓冲区中,等待订阅者订阅相应的频道。
  3. 订阅者通过SUBSCRIBE命令订阅一个或多个频道。
  4. 当有消息发送到已订阅的频道时,Redis将消息发送给订阅者。
  5. 订阅者可以通过UNSUBSCRIBE命令取消订阅某个频道,不再接收该频道的消息

发布订阅模式的常用命令

  • SUBSCRIBE channel [channel ...] :订阅指定的一个或者多个频道(推荐先执行订阅之后再发布,订阅成功之前发布的消息是接收不到的)
ruby 复制代码
127.0.0.1:6379> subscribe c1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
  • PUBLISH channel message:将消息发送到指定的频道
sql 复制代码
--- 发布消息的客户端
[root@gone ~]# redis-cli
127.0.0.1:6379> publish c1 hello_c1
(integer) 2

--- 之前订阅消息的客户端
127.0.0.1:6379> subscribe c1 
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
1) "message"         ------- 消息的种类
2) "c1"              ------- 始发频道的名称
3) "hello_c1"        ------- 实际的消息内容
  • PSUBSCRIBE [pattern [pattern ...]]:订阅一个或多个符合给定模式的频道
arduino 复制代码
-- 这个命令订阅了所有以 "redis1" 开头和以 "redis2" 开头的频道,并输出多条显示订阅成功的消息
PSUBSCRIBE redis1* redis2* 
  • PUBSUB [argument [argument ...]]]:查看订阅与发布系统状态。它由数个不同格式的子命令组成
sql 复制代码
--- 返回活跃频道的列表
127.0.0.1:6379> pubsub channels
1) "c1"
2) "c2"
--- 返回c1频道的订阅者数量
127.0.0.1:6379> pubsub numsub c1
1) "c1"
2) (integer) 3
-- 只统计使用PSUBSCRIBE命令执行的,返回客户端订阅的唯---模式的数量
--- 客户端1下执行
127.0.0.1:6379> psubscribe a* b* c* d*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "a*"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "c*"
3) (integer) 3
1) "psubscribe"
2) "d*"
3) (integer) 4
--- 客户端2下执行
127.0.0.1:6379> pubsub numpat
(integer) 4
  • PUNSUBSCRIBE [pattern [pattern ...]]:退订所有给定模式的频道
arduino 复制代码
--- 命令退订了所有以"redis1"开头和以"redis2"开头的频道,并输出多条显示退订成功的消息
PUNSUBSCRIBE redis1* redis2*
    
  • UNSUBSCRIBE [channel ...]:取消订阅指定的频道
ruby 复制代码
127.0.0.1:6379> unsubscribe c1
1) "unsubscribe"
2) "c1"
3) (integer) 0    

案例演示

  • 开启3个客户端,客户端A、B订阅消息,C发布消息
sql 复制代码
--- 1.客户端A订阅:
127.0.0.1:6379> subscribe c1 
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1    

--- 2.客户端B订阅
127.0.0.1:6379> subscribe c1 
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1 

--- 3.客户端C发布
127.0.0.1:6379> publish c1 'hello channel c1'
(integer) 2 

--- 4.查看客户端A
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
1) "message"
2) "c1"
3) "hello channel c1"
    
--- 5.查看客户端B
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
1) "message"
2) "c1"
3) "hello channel c1"
  • 批量订阅和发布
sql 复制代码
--- 批量订阅
--- 1.客户端A执行
127.0.0.1:6379> psubscribe a* b* c* d*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "a*"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "c*"
3) (integer) 3
1) "psubscribe"
2) "d*"
3) (integer) 4

---2.客户端B执行
127.0.0.1:6379> pubsub numpat
(integer) 4
127.0.0.1:6379> publish c10 hello_channel_c10
(integer) 1
127.0.0.1:6379> publish a11 hello_channel_a11
(integer) 1

--- 3.查看客户端A的信息输出
127.0.0.1:6379> psubscribe a* b* c* d*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "a*"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "c*"
3) (integer) 3
1) "psubscribe"
2) "d*"
3) (integer) 4
    
---- 输出的信息
1) "pmessage"
2) "c*"
3) "c10"
4) "hello_channel_c10"
1) "pmessage"
2) "a*"
3) "a11"
4) "hello_channel_a11"

发布订阅模式的缺点

Redis 的发布-订阅模式是一种非常强大的消息传递机制,它允许订阅者监听一个或多个频道,并在有消息发布到这些频道时接收它们。然而,这种模式也有一些潜在的缺点:

  1. 消息可靠性:在 Redis 的发布订阅模型中,消息是单向传输的。发布者将消息发布到一个通道(channel),然后所有订阅该通道的订阅者都会收到消息。然而,一旦消息被发布,Redis 不提供任何确保消息到达的机制。如果订阅者在消息发布时离线或者处理消息失败,那么消息可能会丢失。
  2. 消息传递的持久性:Redis 的发布订阅模型不保证消息的持久性。如果订阅者在消息发布后关闭或者崩溃,那么消息可能会丢失。为了解决这个问题,可以配置 Redis 持久化消息,但这样会增加额外的性能开销和存储需求。
  3. 消息的顺序性:在 Redis 的发布订阅模型中,多个订阅者可以同时接收到发布者发布的消息。然而,无法保证消息的顺序性。即,不同的订阅者可能会以不同的顺序接收到同样的一系列消息。如果需要严格的消息顺序性,可能需要额外的逻辑来处理。
  4. 消息的确认机制:在 Redis 的发布订阅模型中,没有内置的消息确认机制。当订阅者接收到消息后,它不会向发布者发送确认消息。这可能导致发布者无法确定消息是否成功传递给所有订阅者。为了解决这个问题,可以引入一个确认机制,但会增加系统的复杂性。
  5. 性能和资源利用:在大量并发订阅者和发布者的情况下,Redis 的发布订阅模型可能会对系统性能和资源利用产生影响。为了处理大量的订阅者和发布者,可能需要增加更多的 Redis 实例和网络带宽。此外,如果每个订阅者都接收所有发布的消息,可能会导致大量的网络流量和内存消耗。
相关推荐
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
∝请叫*我简单先生1 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
dessler3 小时前
Docker-run命令详细讲解
linux·运维·后端·docker
Q_19284999063 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
ZSYP-S4 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
Yuan_o_5 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
程序员一诺5 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
DT辰白6 小时前
如何解决基于 Redis 的网关鉴权导致的 RESTful API 拦截问题?
后端·微服务·架构