您的位置:首页 > 数据库 > Redis

Redis发布与订阅操作

2020-07-18 04:31 211 查看

文章目录

  • 2. 发布订阅命令
  • 参考文献
  • 引言

    Redis支持频道订阅和模式订阅;

    • 频道订阅:订阅的频道和发布消息的频道相同时,客户端可以接收到消息,如一个客户端订阅频道
      news.it
      ,则只有频道
      news.it
      的消息才可以发送给该客户端;
    • 模式订阅:一个模式可以匹配一个或多个频道,当发布消息的频道与订阅的频道模式匹配时,客户端可以接收到消息,如一个客户端订阅模式
      news.[ie]t
      ,则它可以接收发布到频道
      news.it
      news.et
      的消息;

    1. 数据结构

    1.1 频道字典

    • 用于频道订阅;
    • 多个客户端可以订阅相同的频道,在服务器的
      redisServer
      结构里有一个
      pubsub_channels
      属性,是一个字典,维护了所有被订阅的频道;
    • 字典的键是被订阅的频道,字典的值则是一个链表,链表里记录了所有订阅这个频道的客户端;
    struct redisServer{
    // ...
    
    // 保存所有频道的订阅关系
    dict *pubsub_channels;
    
    // ...
    };

    2. 模式链表

    • 用于模式订阅;
    • 一个模式可以匹配一个或多个频道;每个客户端订阅的模式可能各不相同,所以将客户端和订阅的模式构建成一个
      pubsubPattern
      结构,然后将多个订阅构成一张链表,存放在
      redisServer
      pubsub_patterns
      属性里;
    struct redisServer{
    // ...
    
    // 保存所有模式订阅关系
    list *pubsub_patterns;
    
    // ...
    };
    
    typedef struct pubsub_pattern{
    // 订阅模式的客户端
    redisClient *client;
    
    // 被订阅的模式
    robj *pattern;
    }pubsub_pattern;

    2. 发布订阅命令

    2.1 订阅频道命令 subscribe

    # 订阅频道 "news.sport" 和 "news.movie"
    SUBSCRIBE "news.sport" "news.movie"

    每当客户端执行

    SUBSCRIBE
    命令订阅某个或某些频道时,服务器都会将客户端与被订阅的频道在
    pubsub_channels
    字典中进行关联:

    • 如果频道已经有其他订阅者(字典中已经存在键为当前频道的订阅者链表),那么服务端直接将客户端添加到订阅者链表的末尾;
    • 如果频道还未有任何订阅者(字典中没有存在键为当前频道的订阅者链表),服务器首先在
      pubsub_channels
      字典中为频道创建一个键,并将这个键的值设置为空链表,然后再将客户端添加到链表,成为链表的第一个元素;

    2.2 退订频道 unscubscribe

    # 退订频道 "news.sport" 和 "news.movie"
    UNSUBSCRIBE "news.sport" "news.movie"

    当一个客户端退订某个频道或者某些频道时,服务器将从

    pubsub_channels
    字典中解除客户端与频道之间的关联:

    • 程序会根据根据退订的频道名字,在
      pubsub_channels
      字典中找到频道对应的订阅者链表,然后从订阅者链表中删除退订客户端的信息;
    • 如果删除退订客户端之后,频道的订阅者链表变成了空链表,那么说明这个频道已经没有任何订阅者了,程序将从
      pubsub_channels
      字典中删除频道对应的键;

    2.3 订阅模式 psubscribe

    # 订阅所有以 "news."开头的频道
    PSUBSCRIBE "news.*"

    订阅模式是服务器端的

    pubsub_patterns
    链表中添加节点;

    每到客户端执行

    PSUBSCRIBE
    命令订阅某个或某些模式时,服务器会对每个被订阅的模式执行以下两个操作:

    • 新建一个
      pubsubPattern
      结构,将结构的
      pattern
      属性设置为被订阅的模式,
      client
      属性设置为订阅该模式的客户端;
    • pubsubPattern
      结构添加到
      pubsub_patterns
      链表的末尾;

    2.4 退订模式 punsubscribe

    # 退订模式 "news.*"
    PUNSUBSCRIBE "news.*"

    当一个客户端退订某个或某些模式的时候,服务器将在

    pubsub_patterns
    链表中查找并删除那些
    pattern
    属性为被退订模式,并且
    client
    属性为执行退订命令的客户端的
    pubsubPattern
    结构

    2.5 发送消息 publish

    PUBLISH <channel> <message>
    
    # 向频道 "news.it"发送 "hello"消息
    PUBLISH "news.it" "hello"

    当一个客户端执行

    PUBLISH
    命令将消息
    message
    发送给频道
    channel
    时,服务器需要执行以下两个操作:

    • 查询
      pubsub_channels
      字典,将消息发送给
      channel
      频道的所有订阅者;
    • 遍历
      pubsub_patterns
      链表,如果某个订阅模式
      pattern
      与频道
      channel
      相匹配,那么将消息发送给
      pattern
      模式的订阅者;

    注意:

    • 发送消息只有一个命令
      PUBLISH
    • PUBLISH
      可以同时将消息发送给频道订阅者模式订阅者

    参考文献

    • 《Redis设计与实现》黄建宏 著,机械工业出版社.
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: