Python--Redis实战:第三章:Redis命令:第六节:发布与订阅

上一篇文章: Python--Redis实战:第三章:Redis命令:第五节:有序集合
下一篇文章: Python--Redis实战:第三章:Redis命令:第七节:其余命令

通常来讲,发布与订阅(又称pub/sub)的特色是订阅者(listener)负责订阅频道(channel),发送者(publisher)负责向频道发送二进制字符串消息(binary string message)。每当有消息被发送至给定频道时,频道的全部订阅者都会收到消息。咱们也能够把频道看做是电台,其中订阅者能够同时收听多个电台,而发送者则能够在任何电台发送信息。redis

本节将对发布与订阅的相关操做进行介绍,阅读这一节可让读者学会怎样使用发布与订阅的相关命令,并了解到为何本书在以后的章节里面会使用其余类似的解决方案来代替Redis提供的发布与订阅。segmentfault

下表展现了Redis提供的5个发布与订阅命令:服务器

命令 用例 用例描述
subscribe subscribe channel [channel ...] 订阅给定的一个或多个频道
unsubscribe unsubscribe [channnel channel ...] 退订给定的一个或多个频道,若是执行时没有给定任何频道,那么退订全部频道
publish publish channel message 向给定频道发送消息
psubscribe psubscribe pattern [pattern ...] 订阅与给定模式相匹配的全部频道
punsunscribe punsunscribe [pattern [pattern ...]] 退订给定的模式,若是执行时没有给定任何模式,那么退订全部模式。

考虑到publish命令和subscribe命令在Python客户端的实现方式,一个比较简单的演示发布与订阅的方法,就像下面代码清单那样使用辅助线程(helper thread)来执行publish命令:网络

import redis  # 导入redis包包
import time,threading


# 与本地redis进行连接,地址为:localhost,端口号为6379

r = redis.StrictRedis(host='localhost', port=6379)

def publisher(n):
    #函数在开始执行时会先休眠,让订阅者有足够的时间来链接服务器并监听消息
    time.sleep(1)
    for i in range(n):
        r.publish('channel',i)
        #在发送消息以后进行短暂的休眠,让消息能够一条接一条地出现
        time.sleep(1)

def run_pubsub():
    #启动发送者线程,并让它发送三条消息
    threading.Thread(target=publisher,args=(3,)).start()
    #建立订阅对象,并对它订阅给定的频道
    pubsub=r.pubsub()
    pubsub.subscribe(['channel'])
    count=0
    #经过遍历函数pubsub.listen()的执行结果来监听订阅消息
    for item in pubsub.listen():
        #打印接收到的每条消息
        print(item)
        count+=1
        if count==4:
            pubsub.unsubscribe()
        if count==5:
            break

if __name__ == '__main__':
    run_pubsub()

运行结果:数据结构

{'type': 'subscribe', 'pattern': None, 'channel': b'channel', 'data': 1}
{'type': 'message', 'pattern': None, 'channel': b'channel', 'data': b'0'}
{'type': 'message', 'pattern': None, 'channel': b'channel', 'data': b'1'}
{'type': 'message', 'pattern': None, 'channel': b'channel', 'data': b'2'}
{'type': 'unsubscribe', 'pattern': None, 'channel': b'channel', 'data': 0}
在刚开始订阅一个频道的时候,客户端会接收到一条关于被订阅频道的反馈。

在退订频道时,客户端会接受到一条反馈信息,告知被退订的是哪一个频道,以及客户端目前仍在订阅的频道数量。函数

虽然Redis的发布与订阅很是有用,但本书只在这一节和8.5节使用了这个模式,这样作的缘由主要有如下两个:操作系统

  • 第一个缘由和Redis系统的稳定性有关。对于旧版Redis来讲,若是一个客户端订阅了某个或某些频道,但它读取消息的速度却不够快的话,那么不断积压的消息会使得Redis输出缓冲区的体积变得愈来愈大,这可能会致使Redis的速度变慢,甚至直接崩溃。也可能会致使Redis被操做系统强制杀死,甚至致使操做系统自己不可用。新版的Redis不会出现这种问题,由于它会自动断开不符合client-output-buffer-limit pubsub配置选项要求的订阅客户端。
  • 第二个缘由和数据传输的可靠性有关。任何网络系统在执行操做时均可能会遇到断线状况,而断线产生的链接错误一般会使得网络链接两端的其中一端进行从新链接。本书使用的Python语言的Redis客户端会在链接失效时自动进程从新链接,也会自动处理链接池(connection pool),诸如此类。可是,若是客户端在执行订阅操做的过程当中断线,那么客户端将丢失在断线期间发送的全部消息,所以依靠频道来接受消息的用户可能会对Redis提供的publish命令和subscribe命令的语义感到失望。

基于以上两个缘由,本书在第六章编写了两个不一样的方法来实现可靠的消息传递操做,这两个方法除了能够处理网络断线以外,还能够防止Redis由于消息挤压而耗费过多内存(这个方法即便对于旧版的Redis也是有效的)。线程

若是你喜欢简单易用的publish命令和subscribe命令,而且可以承担可能会丢失一小部分数据的风险,那么你也能够继续使用Redis提供的发布与订阅特性,而不是8.5节中提供的实现,只要记得先把client-output-buffer-limit pubsub选项设置好就好了。code

到目前为止,本书介绍的大多数命令都是与特定数据类型相关的。接下来的一节要介绍的命令你可能也会用到,但它们既不属于Redis提供的5中数据结构,也不属于发布与订阅特性。对象

上一篇文章: Python--Redis实战:第三章:Redis命令:第五节:有序集合
下一篇文章: Python--Redis实战:第三章:Redis命令:第七节:其余命令
相关文章
相关标签/搜索