如何用Redis实现消息的发布和订阅?实现原理又是什么?

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 学习笔记

大家好,我是卷心菜。本篇主要讲解用Redis实现消息的发布和订阅,如果您看完文章有所收获,可以三连支持博主哦~,嘻嘻。


一、什么是发布和订阅

🎁 作者简介:在校大学生一枚,Java领域新星创作者,Java、Python正在学习中,期待和大家一起学习一起进步~
💗 个人主页:我是一棵卷心菜的个人主页
🔶 本文专栏:Redis理论和实战
📕 自我提醒:多学多练多思考,编程能力才能节节高!
  • Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
  • 特点:Redis 客户端可以订阅任意数量的频道。
  • 这就好比粉丝们关注了我,当我写完文章发布的时候,你们打开CSDN也会接收到我写的文章。此时,我就是发送者(pub);粉丝们就是订阅者(sub)。

结构图如下:发布者发送自己的消息到redis服务器,订阅者从redis服务器中获取发布者发布的消息

在这里插入图片描述


二、Redis的发布和订阅

  • 为了方便后面讲解发布和订阅命令行的使用,我先用两张图简单的介绍redis实现发布和订阅的整体流程。
  • 客户端可以订阅频道如下图:

在这里插入图片描述

  • 当给这个频道发布消息后,消息就会发送给订阅的客户端,如下图:

在这里插入图片描述

三、redis 发布订阅常用命令

  • 下表列出了 redis 发布订阅常用命令:

在这里插入图片描述

四、命令实战

  • 在演示redis消息的发布和订阅之前,我们需要打开两个客户端,一个充当消息发布者,一个充当消息接受者。

1、基本使用

  • 先用一个客户端订阅频道csdn_blog,等待消息:
127.0.0.1:6379> SUBSCRIBE csdn_blog 
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "csdn_blog"
3) (integer) 1
  • 接着一个客户端在csdn_blog频道发送消息hello,cabbage
127.0.0.1:6379> PUBLISH csdn_blog "hello,cabbage"
(integer) 1
  • 最后接受者接收到消息:
1) "message" 
2) "csdn_blog"    # 接收消息所在的频道
3) "hello,cabbage"   # 接收到的消息

2、订阅符合要求的频道

  • 订阅以csdn开头的频道,*表示任意字符
127.0.0.1:6379> PSUBSCRIBE csdn*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "csdn*"
3) (integer) 1
  • 发布者在两个频道发布消息:
127.0.0.1:6379> PUBLISH csdn_blog "hello"
(integer) 1
127.0.0.1:6379> PUBLISH csdn_sing "sing"
(integer) 1
  • 最后订阅者接收到两个频道的消息:
1) "pmessage"
2) "csdn*"
3) "csdn_blog"
4) "hello"
1) "pmessage"
2) "csdn*"
3) "csdn_sing"
4) "sing"

3、查看活跃频道

  • 订阅者订阅两条频道:
127.0.0.1:6379> SUBSCRIBE csdn_one csdn_two
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "csdn_one"
3) (integer) 1
1) "subscribe"
2) "csdn_two"
3) (integer) 2
  • 发布者在三条频道发送消息:
127.0.0.1:6379> PUBLISH csdn_one "one"
(integer) 1
127.0.0.1:6379> PUBLISH csdn_two "two"
(integer) 1
127.0.0.1:6379> PUBLISH csdn_three "three"
(integer) 0
  • 在发布者客户端显示活跃的频道:
127.0.0.1:6379> PUBSUB channels
1) "csdn_one"
2) "csdn_two"

五、发布订阅原理

  • 每个Redis服务器进程都维持着一个表示服务器状态的redis.h/redisServer 结构, 结构的pubsub_channels属性是一个字典, 这个字典就用于保存订阅频道的信息,其中,字典的键为正在被订阅的频道, 而字典的值则是一个链表, 链表中保存了所有订阅这个频道的客户端

1、订阅频道原理

  • 假设订阅频道前有如下图所示的频道和订阅该频道的客户端:从图中可以清楚的知道,channelA频道有三个人订阅;channelB频道没有人订阅;channelC频道有两个人订阅。

在这里插入图片描述

  • 当客户端clientF调用SUBSCRIBE命令时,程序就将客户端和要订阅的频道在 pubsub_channels字典中关联起来。执行以下指令,对应的结果图为:
127.0.0.1:6379> SUBSCRIBE channelB channelC channelA

在这里插入图片描述

  • 结论:通过pubsub_channels字典, 程序只要检查某个频道是否为字典的键,就可以知道该频道是否正在被客户端订阅; 只要取出某个键的值, 就可以得到所有订阅该频道的客户端的信息。

2、发布信息原理

  • 原理说明:当调用PUBLISH channel message命令, 程序首先根据channel定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。
  • 对于上图来说,如果客户端channelA执行命令PUBLISH channelA "hello,cabbage",那么clientAclientBclientCclientF这四个客户端都将接收到"hello,cabbage"信息,通过遍历订阅频道的所有客户端。

3、退订信息原理

  • 原理:使用UNSUBSCRIBE命令可以退订指定的频道,这个命令执行的是订阅的反操作: 它从pubsub_channels字典的给定频道(键)中, 删除关于当前客户端的信息, 这样被退订频道的信息就不会再发送给这个客户端。

参考文章:http://t.zoukankan.com/rxbook-p-12652198.html


感谢阅读,一起进步,嘻嘻~

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
缓存 NoSQL Apache
【Redis】布隆过滤器原理与应用
【Redis】布隆过滤器原理与应用
31 1
|
1月前
|
NoSQL 安全 Unix
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(中)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
26 0
|
4天前
|
监控 NoSQL Java
在 Spring Boot 中实现 Redis 的发布/订阅功能可以通过 RedisTemplate 和消息监听器来完成
在 Spring Boot 中实现 Redis 的发布/订阅功能可以通过 RedisTemplate 和消息监听器来完成
9 1
|
21天前
|
NoSQL Redis 数据库
【Redis从入门到入土】布隆过滤器简介、特点和原理
【6月更文挑战第1天】布隆过滤器是一种节省内存的不确定数据结构,用于判断元素是否可能在一个集合中。它由位数组和多个哈希函数组成,能快速插入和查询,但存在误判风险:可能存在假阳性(判断存在但实际不存在),但绝无假阴性(判断不存在则确实不存在)。适用于大规模数据的去重问题,如电话号码判断、安全网站链接检查、黑名单和白名单校验。其工作原理是通过多个哈希函数将元素映射到位数组中,添加时设置相应位置为1,查询时所有位置都为1则可能存在,有0则肯定不存在。由于哈希冲突,可能导致误判,且一旦添加元素无法删除,以避免影响其他元素。
28 4
|
27天前
|
存储 缓存 NoSQL
Redis与数据库同步指南:订阅Binlog实现数据一致性
本文由开发者小米分享,探讨分布式系统中的一致性问题,尤其是数据库和Redis一致性。文章介绍了全量缓存策略的优势,如高效读取和稳定性,但也指出其一致性挑战。为解决此问题,提出了通过订阅数据库的Binlog实现数据同步的方法,详细解释了工作原理和步骤,并分析了优缺点。此外,还提到了异步校准方案作为补充,以进一步保证数据一致性。最后,提醒在实际线上环境中需注意日志记录、逐步优化和监控报警。
63 3
|
1月前
|
存储 缓存 NoSQL
由菜鸟到大神,谈谈redis的概念、实战、原理、高级使用方法
【5月更文挑战第18天】Redis是一个开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串、哈希、列表、集合、有序集合等。
33 10
|
17天前
|
消息中间件 NoSQL Linux
详解Redis的主从同步原理
只不过在主节点中叫做master_repl_offset; 从节点也有一个偏移量叫做slave_repl_offset,用来记录从节点已经从主节点的repl_backlog_buffer中同步到的最新写指令的位置;
166 0
|
1月前
|
存储 NoSQL API
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(上)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
31 1
|
1月前
|
监控 NoSQL 算法
深入剖析Redis哨兵模式的原理和应用
Redis的哨兵模式是实现高可用性和自动故障转移的机制,当主服务器故障时,哨兵能自动检测并进行故障转移,确保服务连续和稳定性。哨兵模式通过监控主从服务器状态、自动故障转移、防止数据不一致,提高容错能力和负载均衡,降低运维成本,实现高可用性。哨兵通过检测主观下线和客观下线状态,以及选举Leader Sentinel来协调故障转移。Raft算法在其中用于领导者选举和状态一致性。哨兵模式通过综合考虑多种因素选举新主服务器并执行故障转移,保障集群稳定运行。
226 0
深入剖析Redis哨兵模式的原理和应用
|
1月前
|
缓存 NoSQL 算法
【redis】布隆过滤器(Bloom Filter)原理解析与应用
【redis】布隆过滤器(Bloom Filter)原理解析与应用
38 1