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 实例和网络带宽。此外,如果每个订阅者都接收所有发布的消息,可能会导致大量的网络流量和内存消耗。
相关推荐
码爸31 分钟前
flink 批量压缩redis集群 sink
大数据·redis·flink
Adolf_19931 小时前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
海里真的有鱼1 小时前
Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
开发语言·后端·rabbitmq
工业甲酰苯胺1 小时前
Spring Boot 整合 MyBatis 的详细步骤(两种方式)
spring boot·后端·mybatis
微刻时光2 小时前
Redis集群知识及实战
数据库·redis·笔记·学习·程序人生·缓存
新知图书2 小时前
Rust编程的作用域与所有权
开发语言·后端·rust
丁总学Java2 小时前
如何使用 maxwell 同步到 redis?
数据库·redis·缓存
蘑菇蘑菇不会开花~2 小时前
分布式Redis(14)哈希槽
redis·分布式·哈希算法
爱吃南瓜的北瓜2 小时前
Redis的Key的过期策略是怎样实现的?
数据库·redis·bootstrap