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"频道
相关推荐
小吴编程之路7 小时前
MySQL 索引核心特性深度解析:从底层原理到实操应用
数据库·mysql
~莫子7 小时前
MySQL集群技术
数据库·mysql
HalvmånEver7 小时前
7.高并发内存池大页内存申请释放以及使用定长内存池脱离new
java·spring boot·spring
凤山老林7 小时前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
就不掉头发7 小时前
Linux与数据库进阶
数据库
与衫7 小时前
Gudu SQL Omni 技术深度解析
数据库·sql
仰泳的熊猫8 小时前
题目2194:蓝桥杯2018年第九届真题-递增三元组
数据结构·c++·算法
咖啡の猫8 小时前
Redis桌面客户端
数据库·redis·缓存
oradh8 小时前
Oracle 11g数据库软件和数据库静默安装
数据库·oracle
赶路人儿8 小时前
UTC时间和时间戳介绍
java·开发语言