当前位置: 首页 > news >正文

Redis发布订阅

在现代的软件开发中,数据存储和管理是至关重要的一环。Redis,作为一个开源的、内存中的数据结构存储系统,以其出色的性能和灵活的数据结构,赢得了开发者们的广泛喜爱。它不仅可以用作数据库,还可以用作缓存和消息代理。今天,我们要探讨的是 Redis 中一个强大的功能——发布订阅模式。

发布订阅模式是一种消息通信模式,发送者(发布者)发送消息,订阅者接收消息。在 Redis 中,客户端可以订阅任意数量的频道,当有新消息通过 PUBLISH 命令发送给频道时,这个消息会被发送给订阅它的所有客户端。

在接下来的文章中,我们将详细介绍 Redis 的发布订阅模式,包括它的工作原理,如何使用,以及一些常见的使用场景。无论你是刚接触 Redis,还是已经有一定的使用经验,我相信你都能从这篇文章中学到一些新的知识。


文章目录

    • @[toc]
        • 1、Redis发布订阅介绍
          • 1.1、Redis发布订阅概述
          • 1.2、Redis发布订阅与消息队列的区别
        • 2、Redis发布订阅的原理
          • 2.1、Redis实现发布订阅的原理
          • 2.2、Redis实现发布订阅的底层结构
        • 3、发布订阅的命令
          • 3.1、SUBSCRIBE命令
          • 3.2、UNSUBSCRIBE命令
          • 3.3、PUBLISH命令

1、Redis发布订阅介绍

1.1、Redis发布订阅概述

Redis 的发布订阅(Pub/Sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis 客户端可以订阅任意数量的频道。当有新消息通过 PUBLISH 命令发送给频道时,这个消息会被发送给订阅它的所有客户端

img

1.2、Redis发布订阅与消息队列的区别

Redis的发布订阅(Pub/Sub)和消息队列是两种不同的消息传递模式,它们的主要区别在于消息的处理方式和使用场景。

消息的处理方式:

  • 在 Redis 的发布订阅模式中,消息是即时的,也就是说,当消息发布后,只有当前在线且订阅了该频道的客户端才能收到这个消息,消息不会被存储,一旦发布,当前没有在线的客户端将无法接收到这个消息。
  • 在消息队列中,消息是持久化的,消息被发送到队列后,会一直在队列中等待被消费,即使没有在线的消费者,消息也不会丢失,消费者下次上线后可以继续从队列中获取到消息。

使用场景:

  • Redis 的发布订阅模式通常用于实现实时消息系统,比如实时聊天、实时推送通知等。
  • 消息队列通常用于异步处理,解耦复杂系统,比如电商系统中的下单、支付、库存处理等操作,通过消息队列可以使这些操作异步处理,提高系统的响应速度。

总的来说,Redis 的发布订阅模式更适合实时、必须立即处理的场景,而消息队列更适合异步处理、耗时操作的场景。


2、Redis发布订阅的原理

2.1、Redis实现发布订阅的原理

Redis 的发布订阅(Pub/Sub)模式的原理主要涉及到三个命令:SUBSCRIBEUNSUBSCRIBEPUBLISH

  1. SUBSCRIBE 命令:当客户端发送 SUBSCRIBE 命令订阅一个或多个频道时,Redis 服务器会将这些频道添加到该客户端的订阅频道列表中,并向客户端返回一个确认订阅的消息。

  2. UNSUBSCRIBE 命令:当客户端发送 UNSUBSCRIBE 命令退订一个或多个频道时,Redis 服务器会将这些频道从客户端的订阅频道列表中移除,并向客户端返回一个确认退订的消息。

  3. PUBLISH 命令:当客户端发送 PUBLISH 命令发布消息到某个频道时,Redis 服务器会查找所有订阅了这个频道的客户端,并将消息发送给这些客户端。

在 Redis 的内部实现中,服务器维护了一个字典,字典的键是频道的名字,字典的值是一个链表,链表中存储了所有订阅了这个频道的客户端。当有新消息发布到某个频道时,服务器只需要查找这个字典,就可以快速找到需要接收这个消息的所有客户端。

这种实现方式使得 Redis 的发布订阅模式具有很高的效率,可以支持大量的客户端同时订阅同一个频道。

2.2、Redis实现发布订阅的底层结构

Redis 的发布订阅(Pub/Sub)模式的底层结构主要包括两个部分:客户端结构和服务器的Pub/Sub结构。

客户端结构:每个 Redis 客户端都有一个 pubsub_channelspubsub_patterns 两个属性,分别用于存储该客户端订阅的频道和模式。

  • pubsub_channels:这是一个字典,键是订阅的频道名,值是NULL。当客户端订阅一个新的频道时,频道名会被添加到这个字典中;当客户端退订一个频道时,频道名会从这个字典中删除。

  • pubsub_patterns:这是一个链表,存储了所有订阅的模式。每个模式都是一个 redisPubSubPattern 结构,包含了模式本身和订阅这个模式的客户端。

服务器的Pub/Sub结构:Redis 服务器维护了一个 pubsub_channels 字典和一个 pubsub_patterns 链表,用于存储所有的频道和模式。

  • pubsub_channels:这是一个字典,键是频道名,值是一个链表,链表中存储了所有订阅了这个频道的客户端。当有新消息发布到这个频道时,服务器会遍历这个链表,将消息发送给所有的客户端。

  • pubsub_patterns:这是一个链表,存储了所有的模式。每个模式都是一个 redisPubSubPattern 结构,包含了模式本身和订阅这个模式的客户端。当有新消息发布时,服务器会遍历这个链表,查找所有匹配的模式,并将消息发送给订阅了这些模式的客户端。

通过这种方式,Redis 实现了发布订阅模式,使得消息的发布和订阅变得非常高效。


3、发布订阅的命令

3.1、SUBSCRIBE命令

SUBSCRIBE 用于订阅一个或多个频道的信息。

命令格式:SUBSCRIBE channel [channel ...]

  • channel:需要订阅的频道名称,可以是一个或多个。

当客户端发送 SUBSCRIBE 命令订阅一个或多个频道时,服务器会接收到这个命令,并将这些频道添加到客户端的订阅列表中。然后,服务器会向客户端返回一个消息,确认已经订阅了这些频道。

一旦客户端订阅了一个频道,它就会持续监听这个频道,直到客户端发送 UNSUBSCRIBE 命令取消订阅,或者客户端断开连接。

当有新消息发布到这个频道时,服务器会将这个消息发送给所有订阅了这个频道的客户端。

例如,客户端可以发送如下命令订阅名为 mychannel 的频道:

SUBSCRIBE mychannel

服务器会返回如下消息:

1) "subscribe"
2) "mychannel"
3) (integer) 1

这表示客户端已经成功订阅了 mychannel 频道。

3.2、UNSUBSCRIBE命令

UNSUBSCRIBE 是 Redis 发布订阅模式中的一个命令,用于退订一个或多个频道的信息。

命令格式:UNSUBSCRIBE [channel [channel ...]]

  • channel:需要退订的频道名称,可以是一个或多个。如果没有指定频道,则会退订所有频道。

当客户端发送 UNSUBSCRIBE 命令退订一个或多个频道时,服务器会接收到这个命令,并将这些频道从客户端的订阅列表中移除。然后,服务器会向客户端返回一个消息,确认已经退订了这些频道。

例如,客户端可以发送如下命令退订名为 mychannel 的频道:

UNSUBSCRIBE mychannel

服务器会返回如下消息:

1) "unsubscribe"
2) "mychannel"
3) (integer) 0

这表示客户端已经成功退订了 mychannel 频道。如果客户端再次收到 mychannel 频道的消息,那么这些消息将会被忽略。

3.3、PUBLISH命令

PUBLISH 是 Redis 发布订阅模式中的一个命令,用于将消息发送到指定的频道。

命令格式:PUBLISH channel message

  • channel:消息需要发送到的频道名称。
  • message:需要发送的消息内容。

当客户端发送 PUBLISH 命令发布消息到某个频道时,服务器会接收到这个命令,并将消息发送给所有订阅了这个频道的客户端。

例如,客户端可以发送如下命令向名为 mychannel 的频道发布一条消息:

PUBLISH mychannel "hello"

服务器会返回一个整数,表示消息成功发送到的客户端数量。例如:

(integer) 1

这表示消息已经成功发送到了 1 个客户端。如果没有客户端订阅这个频道,那么这个命令将不会有任何效果。

相关文章:

Redis发布订阅

在现代的软件开发中,数据存储和管理是至关重要的一环。Redis,作为一个开源的、内存中的数据结构存储系统,以其出色的性能和灵活的数据结构,赢得了开发者们的广泛喜爱。它不仅可以用作数据库,还可以用作缓存和消息代理。…...

在Windows操作系统上安装PostgreSQL数据库

在Windows操作系统上安装PostgreSQL数据库 一、在Windows操作系统上安装PostgreSQL数据库 一、在Windows操作系统上安装PostgreSQL数据库 点击 PostgreSQL可跳转至PostGreSQL的官方下载地址。 (1) (2)选择安装的目录&#xff…...

【云原生】Kubeadmin部署Kubernetes集群

目录 ​编辑 一、环境准备 1.2调整内核参数 二、所有节点部署docker 三、所有节点安装kubeadm,kubelet和kubectl 3.1定义kubernetes源 3.2开机自启kubelet 四、部署K8S集群 4.1查看初始化需要的镜像 4.2在 master 节点上传 v1.20.11.zip 压缩包至 /opt 目录…...

Java中wait和notify详解

线程的调度是无序的,随机的,但是也是有一定的需求场景,希望能够有序执行,join算是一种控制顺序的方式(功能有限)——》一个线程执行完,才能执行另一个线程! 本文主要讲解的&#xf…...

算法竞赛个人注意事项

浅浅记录一下自己在算法竞赛中的注意事项。 数据类 注意看数大小,数学库中的函数尽量加上 * 1.0,转成double,防止整型溢出。,int型相乘如果可能溢出,乘 * 1LL。 数据范围大于1e6,注意用快读。 浮点数输…...

ClickHouse和Doris超大数据集存储

文章目录 一. ClickHouse1. 性能2. 可靠性3. 可扩展性4. 支持SQL和复杂查询5. 适用场景 二. Doris1. 性能2. 可靠性3. 易用性4. 适用场景 三. ClickHouse和Doris的比较1. 架构2. 性能3. 可靠性4. 易用性5. 适用场景 四. 总结 ClickHouse和Doris是两种流行的超大数据集存储方案。…...

02-Flask-对象初始化参数

对象初始化参数 前言对象初始化参数import_namestatic_url_pathstatic_foldertemplate_floder 前言 本篇来学习Flask中对象初始化参数 对象初始化参数 import_name Flask程序所在的包(模块),传__name__就可以 _name_ 是一个标识 Python 模块的名字的变量&#x…...

第5篇 vue的通信框架axios和ui框架-element-ui以及node.js

一 axios的使用 1.1 介绍以及作用 axios是独立于vue的一个项目,基于promise用于浏览器和node.js的http客户端。 在浏览器中可以帮助我们完成 ajax请求的发送在node.js中可以向远程接口发送请求 1.2 案例使用axios实现前后端数据交互 1.后端代码 2.前端代码 &…...

RabbitMQ 知识点解读

1、AMQP 协议 1.1、AMQP 生产者的流转过程 当客户端与Broker 建立连接的时候,会调用factory .newConnection 方法,这个方法会进一步封装成Protocol Header 0-9-1 的报文头发送给Broker ,以此通知Broker 本次交互采用的是AMQPO-9-1 协议&…...

SimVODIS++: Neural Semantic Visual Odometry in Dynamic Environments 论文阅读

论文信息 题目:SimVODIS: Neural Semantic Visual Odometry in Dynamic Environments 作者:Ue-Hwan Kim , Se-Ho Kim , and Jong-Hwan Kim , Fellow, IEEE 时间:2022 来源: IEEE ROBOTICS AND AUTOMATION LETTERS(RAL…...

7.Xaml Image控件

1.运行图片 2.运行源码 a.xaml源码 <!--Source="/th.gif" 图像源--><!--Stretch="Fill" 填充模式--><Image x:Name...

Solidity 小白教程:11. 构造函数和修饰器

Solidity 小白教程&#xff1a;11. 构造函数和修饰器 这一讲&#xff0c;我们将用合约权限控制&#xff08;Ownable&#xff09;的例子介绍solidity语言中构造函数&#xff08;constructor&#xff09;和独有的修饰器&#xff08;modifier&#xff09;。 构造函数 构造函数&…...

静态工厂模式,抽象工厂模式,建造者模式

静态工厂模式 ublic class FruitFactory {public static Fruit getFruit(String name) {Fruit fnull;switch (name){case "APPLE":{fnew Apple();}case "BANANA":{fnew Banana();}default :{System.out.println("Unknown Fruit");}}return f;} …...

【动手学深度学习笔记】--门控循环单元GRU

文章目录 门控循环单元GRU1.门控隐状态1.1重置门和更新门1.2候选隐状态1.3隐状态 2.从零开始实现2.1读取数据2.2初始化模型参数2.3定义模型2.4训练与预测 3.简洁实现 门控循环单元GRU 学习视频&#xff1a;门控循环单元&#xff08;GRU&#xff09;【动手学深度学习v2】 官方…...

浅析linux异步io框架 io_uring

前言 Linux内核5.1支持了新的异步IO框架iouring&#xff0c;由Block IO大神也即Fio作者Jens Axboe开发&#xff0c;意在提供一套公用的网络和磁盘异步IO&#xff0c;不过io_uring目前在磁盘方面要比网络方面更加成熟。 目录 背景简介 io_uring 系统API liburing 高级特性…...

访问者模式的一个使用案例——文档格式转换

访问者模式的一个使用案例——文档格式转换 假设我们在开发一个文档编辑器&#xff0c;它支持多种不同的文档元素&#xff08;如段落、图片、表格等&#xff09;&#xff0c;现在我们需要添加一个功能——将文档导出为 HTML 或 Markdown 格式。 这就是一个典型的访问者模式的…...

【MySql】数据库的聚合查询

写在最前面的话 哈喽&#xff0c;宝子们&#xff0c;今天给大家带来的是MySql数据库的聚合查询。在前面CRUD章节我们学习了表达式查询&#xff0c;表达式查询是针对列和列之间进行运算的&#xff0c;那么如果想在行和行之间进行运算&#xff0c;那么就需要用到聚合查询。聚合查…...

Linux初探 - 概念上的理解和常见指令的使用

目录 Linux背景 Linux发展史 GNU 应用场景 发行版本 从概念上认识Linux 操作系统的概念 用户的概念 路径与目录 Linux下的文件 时间戳的概念 常规权限 特殊权限 Shell的概念 常用指令 ls tree stat clear pwd echo cd touch mkdir rmdir rm cp mv …...

苹果上架Guideline 4.3 - Design

最近上架苹果商店&#xff0c;审核提示 Guideline 4.3 - DesignWe noticed your app shares a similar binary, metadata, and/or concept as apps previously submitted by a terminated Apple Developer Program account.Submitting similar or repackaged apps is a form o…...

【数据分析入门】【淘宝电商API接入与电商数据分析】初识Web API(一)

今天开始我们将学习如何使用Web应用变成借口(API)自动请求网站到特定信息而不是整个网站&#xff0c;再对这些信息进行可视化。由于这样编写到程序始终使用最新到数据来生成可视化&#xff0c;因此即便数据瞬息万变&#xff0c;它呈现到信息也都是最新的。比如&#xff0c;我们…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...