聊聊 Redis 的高级特性之一: 发布订阅

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。图中,消费者1和消费者2 订阅了 Redis 服务的频道 channel ,当生产者通过 PUBLISH 命令发送给频道 channel 时, 这个消息就会被发送给订阅它的两个客户端。

这篇文章,我们聊聊 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 实战演示

笔者开源了一个短信服务,为了提升系统性能,应用信息存储在本地内存中,定时任务会每隔30秒重新刷新一次缓存。

但在分布式部署的场景下,不同应用间的本地内存数据可能因为执行时间差异导致数据不同步。

基于这样的场景,我们可以使用 Redis 的发布订阅功能,实现本地内存的及时刷新。

1、配置 Redis 频道监听器容器

2、触发发布消息

当应用发送变化时,比如新增、修改、删除,则调用发送消息到频道方法。

下图,当我们启动两个短信平台应用,在控制台修改应用信息时,我们发现两个应用的本地内存都发生变化了。

6 总结

  1. Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

​ 消费者1和消费者2 订阅了 Redis 服务的频道 channel ,当生产者通过 PUBLISH 命令发送给频道 channel 时, 这个消息就会被发送给订阅它的两个客户端。

  1. 在使用发布订阅功能时,需要理解两点。

    • 保证先让消费者先订阅队列,然后再让生产者发布消息。

    • 发布订阅不具备数据持久化的能力。

  2. 发布订阅功能特别适合对少量消息丢失不敏感通知类型的场景。

  3. 笔者开源的短信平台项目,使用了 Redis 的发布订阅功能实现本地内存的实时同步。

短信平台地址https://github.com/makemyownlife/platform-sms


参考资料:

https://redisbook.readthedocs.io/en/latest/feature/pubsub.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 Redis
Redis 发布订阅
10月更文挑战第18天
29 1
Redis 发布订阅
|
26天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
62 10
|
1月前
|
存储 消息中间件 NoSQL
【redis】redis的特性和主要应用场景
【redis】redis的特性和主要应用场景
109 1
|
1月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
248 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
2月前
|
消息中间件 存储 NoSQL
18)Redis 的发布订阅模型
18)Redis 的发布订阅模型
33 0
|
4月前
|
消息中间件 缓存 NoSQL
Redis快速度特性及为什么支持多线程及应用场景
Redis快速度特性及为什么支持多线程及应用场景
114 11
|
3月前
|
NoSQL Java 调度
Lettuce的特性和内部实现问题之Redis的管道模式提升性能的问题如何解决
Lettuce的特性和内部实现问题之Redis的管道模式提升性能的问题如何解决
|
3月前
|
NoSQL 网络协议 安全
Lettuce的特性和内部实现问题之Lettuce天然地使用管道模式与Redis交互的问题如何解决
Lettuce的特性和内部实现问题之Lettuce天然地使用管道模式与Redis交互的问题如何解决
|
5月前
|
监控 NoSQL 网络安全
Redis 6和7:探索新版本中的新特性
Redis 6和7:探索新版本中的新特性
|
6月前
|
存储 NoSQL 关系型数据库
redis-学习笔记(概念, 相关名词, 特性, 优势: 快)
redis-学习笔记(概念, 相关名词, 特性, 优势: 快)
38 0
下一篇
无影云桌面