Redis中的订阅发布(一)

订阅发布

概述

Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。通过执行SUBSCRIBER命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者(subscribe):

每当有其他客户端向被订阅的频道发送消息(message)时,频道的所有订阅者都会收到这条消息.

除了订阅频道之外,客户端还可以通过执行PSUBSCRIBE命令订阅一个或多个模式,从而成为这些模式的订阅者:每当有其他客户端向某个频道发送消息时,消息不仅会被发送给这个频道的所有订阅者,它还会被发送给所有与这个频道相匹配的模式的订阅者

例子

  • 举个例子。假设A、B、C三个客户端都执行了命令:
c 复制代码
SUBSCRIBE "news.it"

那么这三个客户端就是"news.it"频道的订阅者,如图所示。如果这时某个客户端执行命令

c 复制代码
PUBLISH "news.it" "hello"

向"news.it"频道发送消息"hello",那么"news.it"的三个订阅者都将收到这条消息,如图所示.

  • 举个例子。假设如图所示:
    1.客户端A正在订阅频道"news.it"
    2.客户端B正在订阅频道"news.et"
    3.客户端C和客户端D正在订阅与"news.it"频道和"news.et"频道相匹配的模式"news.[ie]t".
    如果这时某个客户端执行命令
c 复制代码
PUBLISH "news.it" "hello"

"news.it"频道发送消息"hello",那么不仅正在订阅"news.it"频道的客户端A会受到消息,客户端C和客户端D也会收到消息,因为这两个客户端正在订阅匹配"news.it"频道的"news.[ie]t"模式,如图所示,

与此类似,如果某个客户端执行命令

c 复制代码
PUBLISH "news.et" "world"

"news.et"频道发送消息"world",那么不仅正在订阅"news.et"频道的客户端B会收到消息,客户端C和客户端D也同样会收到消息。因为这两个客户端正在订阅匹配"news.et"频道的"news.[ie]t"模式,如图所示


Redis中的发布订阅会进行持久化吗?

在Redis中,发布订阅(Pub/Sub)模式本身并不会进行消息的持久化。当消息被发布到频道时,它们会被发送给当前处于订阅状态的客户端,并在这些客户端中进行传递,但不会被持久化到磁盘上。如果需要对消息进行持久化,可以考虑以下几种方法:

  • 1.使用Redis Streams:Redis5.0引入了Streams数据结构,它提供更丰富的消息传递功能,并且支持消息的持久化。可以将消息发送到RedisStreams中,然后消费者可以按需读取消息,并且这些消息会持久化到Redis中
  • 2.将消息存储到数据库中:在订阅者接收到消息后,可以将消息存储到数据库中进行持久化。这样可以确保即使在Redis发布订阅模式中没有持久化消息的情况下,仍然可以通过数据库来获取消息历史记录
  • 3.使用Redis AOF持久化:如果仍然希望使用Redis发布订阅模式,并且希望对消息进行持久化,可以启用Redis的AOF(Append-Only File)持久化功能。AOF记录了Redis服务器接收到的所有写命令,包括发布消息到频道的命令。通过启用AOF持久化,可以确保即使Redis服务器重启,也不会丢失消息

综上所述,Redis发布订阅模式本身并不提供消息持久化功能,但可以通过其他方式来实现消息的持久化,来满足需求

频道的订阅与退订。

当一个客户端执行SUBSCRIBE命令订阅某个或某些频道的时候,这个客户端与被订阅频道之间建立起了一种订阅关系。Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channels字典里面,这个字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面记录了所有订阅这个频道的客户端:

c 复制代码
struct redisServer {
// ...

// 保存所有频道的订阅关系
dict *pubsub_channels:

// ...
};

例子

  • 举个例子。如图展示了一个pubsub_channels字典示例,这个字典记录了以下信息:
    1.client-1、client-2、client-3三个客户端正在订阅"news.it"频道
    2.客户端client-4正在订阅"news.sport"频道
    3.client-5和client-6两个客户端正在订阅"news.business"频道
相关推荐
闻哥几秒前
Kafka高吞吐量核心揭秘:四大技术架构深度解析
java·jvm·面试·kafka·rabbitmq·springboot
金牌归来发现妻女流落街头2 分钟前
【Springboot基础开发】
java·spring boot·后端
这周也會开心6 分钟前
Redis数据类型的底层实现和数据持久化
数据库·redis·缓存
ん贤7 分钟前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
数据知道18 分钟前
PostgreSQL 核心原理:系统内部的对象寻址机制(OID 对象标识符)
数据库·postgresql
考琪18 分钟前
Nginx打印变量到log方法
java·运维·nginx
wangjialelele29 分钟前
Linux中的进程管理
java·linux·服务器·c语言·c++·个人开发
历程里程碑30 分钟前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
sin_hielo31 分钟前
leetcode 1653
数据结构·算法·leetcode
李日灐35 分钟前
C++进阶必备:红黑树从 0 到 1: 手撕底层,带你搞懂平衡二叉树的平衡逻辑与黑高检验
开发语言·数据结构·c++·后端·面试·红黑树·自平衡二叉搜索树