一文讲透Redis高级特性:发布订阅(redisson 发布订阅)
mhr18 2024-10-29 14:34 31 浏览 0 评论
这篇文章,我们聊聊 Redis 的高级特性之一: 发布订阅。
1 发布订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
图中,消费者1和消费者2 订阅了 Redis 服务的频道 channel ,当生产者通过 PUBLISH 命令发送给频道 channel 时, 这个消息就会被发送给订阅它的两个客户端。
下表列出了 Redis 发布订阅常用命令:
命令 | 用法 | 描述 |
PSUBSCRIBE | PSUBSCRIBE pattern [pattern ...] | 订阅一个或多个符合给定模式的频道 |
PUBSUB | PUBSUB subcommand [argument [argument ...]] | 查看订阅与发布系统状态 |
PUBLISH | PUBLISH channel message | 将信息发送到指定的频道 |
PUNSUBSCRIBE | PUNSUBSCRIBE [pattern [pattern ...]] | 退订所有给定模式的频道 |
SUBSCRIBE | SUBSCRIBE channel [channel ...] | 订阅给定的一个或多个频道的信息 |
UNSUBSCRIBE | UNSUBSCRIBE [channel [channel ...]] | 指退订给定的频道 |
2 客户端演示
我们开启两个 redis-cli 客户端,演示了发布订阅是如何工作的。
客户端 A 执行订阅命令:
subscribe mychannel
订阅命令执行成功后:
客户端 B 执行发布命令:
publish mychannel helloworld
发布命令执行成功后,客户端 A 就会接收到新的消息:
3 实现原理
每个 Redis 服务器进程都维持着一个表示服务器状态的 redis.h/redisServer 结构, 结构的 pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息:
struct redisServer {
// ...
dict *pubsub_channels;
// ...
};
其中,字典的键为正在被订阅的频道, 而字典的值则是一个链表, 链表中保存了所有订阅这个频道的客户端。
下图中, client2 、 client5 和 client1 就订阅了 channel1 , 而其他频道也分别被别的客户端所订阅:
当客户端调用 SUBSCRIBE 命令时, 程序就将客户端和要订阅的频道在 pubsub_channels 字典中关联起来。
举个例子,如果客户端 client10086 执行命令 SUBSCRIBE channel1 channel2 channel3 ,那么前面展示的 pubsub_channels 将变成下面这个样子:
当调用 PUBLISH channel message 命令, 程序首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。
如果某个客户端执行命令 PUBLISH channel1 "hello moto" ,那么 client2 、 client5 和 client1 三个客户端都将接收到 "hello moto" 信息:
4 适用场景
在使用发布订阅功能时,需要理解两点。
1、保证先让消费者先订阅队列,然后再让生产者发布消息。
如果消费者异常挂掉并重新上线,它只能接收新的消息。在其下线期间,生产者发布的消息将无法被消费者接收,因为找不到该消费者,这些消息会被丢弃。
如果所有消费者都下线,那么生产者发布的消息将因为没有任何消费者而全部被丢弃。
2、发布订阅不具备数据持久化的能力
发布订阅相关的操作不会被写入到 Redis 数据库(RDB)或追加写入文件(AOF)中。如果 Redis 宕机并重新启动,Pub/Sub 的数据将会全部丢失。
基于上面的分析,发布订阅功能特别适合对少量消息丢失不敏感的通知类型的场景
5 SpringBoot 演示
笔者开源了一个短信服务,为了提升系统性能,应用信息存储在本地内存中,定时任务会每隔30秒重新刷新一次缓存,但在分布式部署的场景下,不同应用间的数据可能没有及时同步。
我们可以使用 Redis 的发布订阅功能,实现本地内存的及时刷新。
1、配置 Redis 频道监听器容器
2、触发发布消息
当应用发送变化时,比如新增、修改、删除,则调用发送消息到频道方法。
下图,当我们启动两个应用,修改应用信息时,我们发现两个应用的本地内存都发生变化了。
参考资料:
https://redisbook.readthedocs.io/en/latest/feature/pubsub.html
相关推荐
- 软件测试流程之数据库基础点(软件测试数据库知识)
-
扼要:1、了解当前流行的数据库有哪些;2、掌握基本的数据库命令;数据库,对测试人员来说,是必须要懂得的技能,不需要太精通,但要了解其大的概念、分类,掌握基本操作命令即可。甚至在一些公司中,测试人员还要...
- 什么是安全运维工程师(安全运维怎么样)
-
什么是安全运维工程师安全运维工程师是网络安全大方向下网络安全运行与维护岗的一个细分岗位。IT运维工作方向比较多,例如系统运维、应用运维、数据库运维、运维安全等。今天我们就来了解运维安全是指什么?怎么成...
- 成为运维大神要掌握哪些知识?终于有人说明白了!
-
在阅读文章前,辛苦您点下“关注”,方便讨论和分享。作者定会不负众望,按时按量创作出更优质的内容。要成为运维大神,需要掌握以下多方面的知识:一、操作系统知识1.Linux系统熟练掌握Linux...
- 程序员常用的编程工具有哪些?(程序员常用的工具软件)
-
1、编辑器:SublimeText、Vim、VisualStudioCode、Atom等。2、编程语言:Java、C++、Python、Javascript、PHP等。3、调试工具:GDB、...
- 升级JDK17的理由,核心是降低GC时间
-
升级前后对比升级方法1.JDK选择或安装2.JVM参数调整背景TLDR垃圾回收器的暂停问题对实时响应要求较高的服务来说,一直是个痛点,CMS和G1等主流垃圾回收器的数十毫秒乃至上百毫秒的暂停...
- JDK 21:GC 不断改进,性能更上一层楼
-
随着2023年秋季发布的JDK21,现在有一个新的LTS版本可以进行基准测试并生成一些GC性能图表。JDK21和自JDK17以来的其他版本提供了一系列值得注意的功能,如虚拟线...
- 大数据开发工程师面试主要面试内容
-
大数据近年来,发展如火如荼,很多人都选择学习大数据专业或者转行大数据,大数据里又包含很多就业岗位,那么,我们在面试大数据开发工程师时,需要面试哪些内容呢。一起来看看!首先,不同岗位、不同公司、不同面试...
- java程序员面试时经常被问到的10个问题
-
java程序员,尤其是做web开发的,面试时,面试官最喜欢问到以下10个问题,掌握面试的动态和技巧,有利于提高我们面试的成功率,了解以下10个问题,有利于java程序员的面试。1、简单描述一下Log4...
- 深入剖析 SQL 调优:导致性能瓶颈的语法问题、优化策略及面试题
-
在企业级应用开发中,数据库作为数据存储与检索的核心组件,其性能直接影响系统的响应速度与稳定性。而SQL语句作为与数据库交互的语言,编写的优劣往往决定了查询效率的高低。本文将聚焦于导致SQL性能...
- MySQL面试题整理:从基础到高级的全面覆盖
-
基础问题什么是MySQL?它与其他数据库管理系统有何不同?MySQL是一个开源关系数据库管理系统(RDBMS),它使用结构化查询语言(SQL)来管理和操作数据。与其他数据库管理系统(如Oracle、M...
- JDK从8升级到21的问题集(jdk8版本)
-
一、背景与挑战1.升级动因oOracle长期支持策略o现代特性需求:协程、模式匹配、ZGC等o安全性与性能的需求oAI新技术引入的版本要求2.项目情况o100+项目并行升级的协同作战o多技术栈并存o持...
- 科莱特SAP ABAP干货 | 基础篇:二、数据字典(1)
-
ABAP开发基础及应用二、数据字典(1)目标及说明目标:1、掌握SAP数据字典各种对象的定义和使用2、能根据业务数据要求,建立存储数据用的表和视图需求说明:1、在SAP中自建程序,以对一企业(自由行集...
- Mycat入门(mycatalog)
-
一、Linux系统下搭建Mycat注:如果没有服务器可以选择虚拟机进行操作1、首先准备好服务器或者虚拟机2、安装和配置MySQL数据库2.1、删除原来的数据库//查询已安装的mariadb[root...
- MySQL从入门到实战:表设计、索引优化与高频面试解析
-
一、业务场景驱动表设计:电商订单系统案例场景背景某电商平台需设计用户、商品、订单模块,要求支持以下操作:用户高频查询最新订单按商品分类+价格区间筛选商品统计每日订单金额建表实战--用户表(反范式设计...
- oracle生成AWR报告的两种方法(oracle中awr报告的输出格式有哪些)
-
方法1:sqlplus中执行:execdbms_workload_repository.create_snapshot();@?/rdbms/admin/awrrpt.sql方法2:setpage...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)