服务器(11)--Redis发布和订阅(pub/sub)

2024-08-26 10:38

本文主要是介绍服务器(11)--Redis发布和订阅(pub/sub),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Redis发布订阅

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

Redis 客户端可以订阅任意数量的频道。

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:


二、特点&问题&解决方案

"发布/订阅"在redis中,被设计的非常轻量级和简洁,它做到了消息的“发布”和“订阅”的 基本能力;

但是尚未提供关于消息的持久化等各种企业级的特性。

一个Redis client发布消息,其他多个redis client订阅消息,发布的消息“即发即失”,redis 不会持久保存发布的消息;

消息订阅者也将只能得到订阅之后的消息,通道中此前的消息将无 从获得。

消息发布者,即publish客户端,无需独占链接,你可以在publish消息的同时,使用同一个redis-client链接进行其他操作(例如:INCR等)

消息订阅者,即subscribe客户端,需要独占链接,即进行subscribe期间,redis-client无法穿插其他操作, 此时client以阻塞的方式等待“publish端”的消息;因此这里subscribe端需要使用单独的链接,甚至需要在额外的线程中使用。 Tcp默认连接时间固定,如果在这时间内sub端没有接收到pub端消息,或pub端没有消息产生,sub端的连接都会被强制回收, 这里就需要使用特殊手段解决,用定时器来模拟pub和sub之间的保活机制,定时器时间不能超过TCP最大连接时间,具体根据机器环境来定;
            一旦subscribe端断开链接,将会失去部分消息,即链接失效期间的消息将会丢失,所以这里就需要考虑到借助redis的list来持久化;

如果你非常关注每个消息,那么你应该基于Redis做一些额外的补充工作,如果你期望订阅是持久的,那么如下的设计思路可以借鉴:

1) subscribe端: 首先向一个Set集合中增加“订阅者ID”, 此Set集合保存了“活跃订阅”者, 订阅者ID标记每个唯一的订阅者,此Set为 "活跃订阅者集合"

2) subcribe端开启订阅操作,并基于Redis创建一个以 "订阅者ID" 为KEY的LIST数据结构, 此LIST中存储了所有的尚未消费的消息,此List称为 "订阅者消息队列"

3) publish端: 每发布一条消息之后,publish端都需要遍历 "活跃订阅者集合",并依次 向每个 "订阅者消息队列" 尾部追加此次发布的消息.

4) 到此为止,我们可以基本保证,发布的每一条消息,都会持久保存在每个 "订阅者消息队列" 中.

5) subscribe端,每收到一个订阅消息,在消费之后,必须删除自己的 "订阅者消息队列" 头部的一条记录.

6) subscribe端启动时,如果发现自己的 "订阅者消息队列" 有残存记录, 那么将会首先消费这些记录,然后再去订阅.

以上方法可以保证成功到达的消息必消费不丢失;

三、实例

创建了订阅频道名为 pubSubTest:

现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。

订阅者接到的消息:

四、Python中的使用

1、发布订阅类

class RedisPubSub:"""Redis 发布订阅类:return:"""def __init__(self, channel):self.__conn = redis.Redis(host="127.0.0.1", port=6379, db=0)self.chan_pub = channelself.chan_sub = channeldef publish(self, msg):"""发布:param msg::return:"""self.__conn.publish(self.chan_pub, msg)return Truedef subscribe(self):"""订阅:return:"""pub = self.__conn.pubsub()pub.subscribe(self.chan_sub)pub.parse_response()return pub

2、发布

# 发布
test_id = 2
# 订阅频道名称
obj = RedisPubSub("pubSubTest")
obj.publish('{"test_id":' + str(test_id) + '}')

结果:

3、订阅

# 订阅
obj = RedisPubSub("pubSubTest")
redis_sub = obj.subscribe()
while True:msg = redis_sub.parse_response()print(msg)print(msg[2])

结果:

 

这篇关于服务器(11)--Redis发布和订阅(pub/sub)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108329

相关文章

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现

Redis中管道操作pipeline的实现

《Redis中管道操作pipeline的实现》RedisPipeline是一种优化客户端与服务器通信的技术,通过批量发送和接收命令减少网络往返次数,提高命令执行效率,本文就来介绍一下Redis中管道操... 目录什么是pipeline场景一:我要向Redis新增大批量的数据分批处理事务( MULTI/EXE

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

Redis中的常用的五种数据类型详解

《Redis中的常用的五种数据类型详解》:本文主要介绍Redis中的常用的五种数据类型详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis常用的五种数据类型一、字符串(String)简介常用命令应用场景二、哈希(Hash)简介常用命令应用场景三、列表(L

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给