zoukankan      html  css  js  c++  java
  • Redis系列(八):发布与订阅

    Redis的发布与订阅,有点类似于消息队列,发送者往频道发送消息,频道的订阅者接收消息。

    1. 发布与订阅示例

    首先,在本机开启第1个Redis客户端,执行如下命令订阅blog.redis频道:

    SUBSCRIBE "blog.redis"
    

    然后,在本机开启第2个Redis客户端,执行相同的命令订阅blog.redis频道:

    然后,开启第3个Redis客户端,执行如下命令往blog.redis频道发送消息:

    PUBLISH blog.redis "redis-in-action-01"
    

    查看客户端1和客户端2,分别看到如下信息:

    3个客户端与频道的关系如下图所示:

    可以通过INFO clients命令查看连接的客户端数:

    2. 订阅/退订频道

    2.1 订阅频道

    Redis的SUBSCRIBE命令用来订阅频道,使用方式如下所示:

    SUBSCRIBE "blog.redis"
    

    如果是订阅多个频道,可以使用如下所示命令:

    SUBSCRIBE "blog.redis" "blog.rocketmq"
    

    Redis将所有频道的订阅关系保存在服务器状态的pubsub_channels字典里,字典的键是某个被订阅的频道,键对应的值是1个链表,链表里记录了所有订阅这个频道的客户端。

    以上图为例,说明客户端1、客户端2正在订阅频道"blog.redis",客户端3、客户端4正在订阅频道“blog.rocketmq”。

    如果此时有1个客户端5,执行了如下命令:

    SUBSCRIBE "blog.rocketmq" "blog.java"
    

    那么服务器状态保存的频道订阅关系将变为如下图所示:

    2.2 退订频道

    Redis的UNSUBSCRIBE命令用来退订频道,使用方式如下所示:

    UNSUBSCRIBE "blog.redis"
    

    如果是退订多个频道,可以使用如下所示命令:

    UNSUBSCRIBE "blog.redis" "blog.rocketmq"
    

    假设现在服务器状态保存的频道订阅关系如下图所示:

    如果此时客户端5,执行了如下命令:

    UNSUBSCRIBE "blog.rocketmq" "blog.java"
    

    那么服务器状态保存的频道订阅关系将变为如下图所示:

    3. 订阅/退订模式

    3.1 示例

    首先,启动1个Redis客户端,执行如下命令订阅模式“blog.r*”:

    PSUBSCRIBE "blog.r*"
    

    然后,启动另1个Redis客户端,执行PUBLISH命令往频道发送消息:

    PUBLISH "blog.redis" "redis-in-action-01"
    
    PUBLISH "blog.rocketmq" "rocketmq-in-action-01"
    
    PUBLISH "blog.java" "java-in-action-01"
    

    可以看到,第1次启动的客户端可以接收到前2条消息,因为频道"blog.redis"、"blog.rocketmq"匹配模式“blog.r*”:

    但频道"blog.java"不匹配该模式,所以最后1次发送的消息,该客户端未接收到。

    3.2 订阅模式

    Redis的PSUBSCRIBE命令用来订阅模式,使用方式如下所示:

    PSUBSCRIBE "blog.r*"
    

    如果是订阅多个模式,可以使用如下所示命令:

    PSUBSCRIBE "blog.r*" "blog.j?va" "blog.j[ae]va"
    

    Redis将所有模式的订阅关系保存在服务器状态的pubsub_patterns属性里。

    pubsub_patterns属性是1个链表,链表中的每个节点是1个pubsub_Pattern结构,这个结构的pattern属性记录被订阅的模式,client属性记录订阅模式的客户端。

    以上图为例,说明客户端1正在订阅模式"blog.r*,客户端2正在订阅模式“blog.j?va”。

    如果此时有1个客户端3,执行了如下命令:

    PSUBSCRIBE "blog.j[ae]va"
    

    那么服务器状态保存的模式订阅关系将变为如下图所示:

    3.3 退订模式

    Redis的PUNSUBSCRIBE命令用来退订模式,使用方式如下所示:

    PUNSUBSCRIBE "blog.r*"
    

    如果是退订多个模式,可以使用如下所示命令:

    PUNSUBSCRIBE "blog.j?va" "blog.j[ae]va"
    

    假设现在服务器状态保存的模式订阅关系如下图所示:

    如果此时客户端3,执行了如下命令:

    PUNSUBSCRIBE "blog.j[ae]va"
    

    那么服务器状态保存的模式订阅关系将变为如下图所示:

    4. 发送消息

    如果,服务器状态保存的频道订阅关系如下图所示:

    服务器状态保存的模式订阅关系如下图所示:

    此时,如果1个Redis客户端执行了以下PUBLISH命令:

    PUBLISH blog.redis "redis-in-action-01"
    

    那么,服务器会执行以下2个动作:

    1. 将消息"redis-in-action-01"发送给频道“blog.redis”的所有订阅者
    2. 将消息"redis-in-action-01"发送给与频道“blog.redis”相匹配模式的订阅者

    也就是说,消息"redis-in-action-01"不仅会发送给频道“blog.redis”的订阅者客户端1、客户端2,也会发送给与频道“blog.redis”相匹配的模式“blog.r*”的订阅者客户端5。

    5. 查看订阅信息

    可以使用Redis的PUBSUB命令来查看频道或者模式的相关信息。

    5.1 查看被订阅的频道

    如果想要查看被订阅的频道信息,可以使用命令PUBSUB CHANNELS [pattern],其中pattern参数是可选的:

    1. 如果不指定pattern参数,返回服务器当前被订阅的所有频道
    2. 如果指定pattern参数,返回服务器被订阅的频道中与pattern模式相匹配的频道

    这个命令的实现原理是通过遍历服务器状态保存的pubsub_channels字典来实现的。

    举个具体的例子,如果服务器状态保存的pubsub_channels字典如下所示:

    那么执行命令PUBSUB CHANNELS的返回结果如下所示:

    执行命令PUBSUB CHANNELS r*的返回结果如下所示:

    5.2 查看频道的订阅者数量

    如果想要查看频道的订阅者数量,可以使用命令PUBSUB NUMSUB [channel1 channel2 ... channeln]

    这个命令的实现原理是通过遍历服务器状态保存的pubsub_channels字典来实现的,频道对应的订阅者链表的长度就是该频道的订阅者数量。

    举个具体的例子,如果服务器状态保存的pubsub_channels字典如下所示:

    那么执行命令PUBSUB NUMSUB blog.redis blog.rocketmq blog.java的返回结果如下所示:

    5.3 查看被订阅模式的数量

    如果想要查看被订阅模式的数量,可以使用命令PUBSUB NUMPAT

    这个命令的实现原理是返回服务器状态保存的pubsub_patterns链表的长度。

    举个具体的例子,如果服务器状态保存的pubsub_patterns链表如下所示:

    那么执行命令PUBSUB NUMPAT的返回结果如下所示:

    6. 总结

    Redis的发布与订阅有点类似于消息队列的发布与订阅,主要包含以下7个命令:

    1. SUBSCRIBE
    2. UNSUBSCRIBE
    3. PSUBSCRIBE
    4. PUNSUBSCRIBE
    5. PUBSUB CHANNELS
    6. PUBSUB NUMSUB
    7. PUBSUB NUMPAT

    这7个命令的核心都是基于存储在服务器状态的pubsub_channels字典和pubsub_patterns链表实现的。

    7. 参考

    黄健宏 《Redis设计与实现》


  • 相关阅读:
    cscope的使用
    关于函数指针
    linux内核源码目录(转)
    lcc之内存分配
    符号管理之符号表
    监听UITextFiled文本发生改变
    Debugging Tools for Windows__from WDK7
    WinDBG__独立安装文件
    20160215
    QT Creator 代码自动补全
  • 原文地址:https://www.cnblogs.com/zwwhnly/p/13209968.html
Copyright © 2011-2022 走看看