【Redis】redis介绍-订阅推送(pub/sub)模式

时间:2022-06-29 22:37:23
redis是kv内存数据库,以其设计优雅、性能优良而著称,接下来对redis开始有一系列的文章介绍。

本篇文章对redis中使用pub/sub的模式进行讲解。

模式介绍


所谓pub/sub模式,是消息通讯的一种,它和消息队列在一定程度上有相似之处。pub/sub模式通过订阅与发布模式来解耦两个相互依赖的模块。消息发送者面向特定主题发送消息,而不是面向特定订阅者发送消息。订阅者也是是 通过订阅感兴趣的主题,接受感兴趣的主题发来的消息。通过彼此之间不相互依赖,而是通过中间主题来使两个紧耦合的模块解耦,不必关系对端是否订阅,或者是否修改订阅关系。
【Redis】redis介绍-订阅推送(pub/sub)模式


对于redis本身,提供了pub/sub的支持。下面简单模拟pub/sub模式的整个过程,打开两个redis客户端,在这里分别pub_cli与sub_cli。
sub_cli:
127.0.0.1:6379> SUBSCRIBE first   //订阅一个频道
执行命令之后,消息返回
127.0.0.1:6379> SUBSCRIBE first
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "first"
3) (integer) 1

pub_cli:
127.0.0.1:6379> PUBLISH first Hello //向频道first发送消息Hello
这个时候在sub_cli就可以发现一条消息打印出来
sub_cli:
127.0.0.1:6379>
Hello。

除了我们显式指定订阅某一个频道之外,我们还可以通过模式匹配原则,订阅符合某一种模式的所有频道。
127.0.0.1:6379> PSUBSCRIBE first*  //订阅所有符合first开头模式的频道

相应的取消订阅就是USUBSCRIBE、PUNSUBSCRIBE 。这里就不再细说,语法格式是一样的。
在pub/sub模式中需要注意,当发布者发布一条消息的时候,如果没有订阅订阅该主题,那么该条消息就永远的丢失了。无论是否该主题在接下来是否有订阅者订阅。在这一点上还有有别于其他的消息队列。比如kafka,它是不会删除消息的,除非你有配置定时删除或者固定大小以后删除。

实现


结合redis自带的pub/sub,可以简单的实现pub/sub模式,在项目中进行运用。下面就通过python模拟整个过程。
对于订阅者,获取pub的信息有三种模式。
get_message、listen,最后一种是创建一个线程来单独负责获取pub信息。 对于get_message是使用了系统的select模式,如果有数据则读取数据并返回,如果没有数据则该方法直接返回空。而listen则是阻塞式读取,只到有信息才返回。 在python的redis客户端2.10之前,get_message方法还没出现是无法使用的,只能是采用listen方法。另外需要注意的是,第三种方法因为是单独创建了一个线程去读取发布者的消息,所以如果在订阅某个主题的时候没有创建默认的处理消息的方法,那么该方式下就不能对发布者的信息进行正常处理了。

pub.py
import time 
import redis
r = redis.StrictRedis(host = "127.0.0.1", port = 6379, db=1)
i = 0
while True:
i += 1
r.publish("first channel", "the i is " + str(i))
print("the i is " + str(i))
time.sleep(1)

sub.py
import time 
import redis
r = redis.StrictRedis(host = "127.0.0.1", port = 6379, db=1)
p = r.pubsub()
p.subscribe("first channel")
while True:
message = p.listen()
if message:
print message


pub_sub:http://redis.io/topics/pubsub