欢迎阅读大魔王的睡前私语系列,这是Redis第九篇文章


发布与订阅

Redis的发布订阅功能由PUBISH,SUBSCRIBE,PSUBSCRIBE命令组成。
通过执行SUBSCRIBE命令,客户端可以订阅一个或者多个频道,从而成为这些频道的订阅者(subscriber):每当有其他客户端向被订的频道发送消息时,频道的所有订阅者都会收到这条消息。

除了订阅频道之外,客户端还可以通过执行PSUBSCRIBE命令订阅一个或者多个模式,从而成为这些模式的订阅者:每当有其他客户端向莫格频道发送消息时,消息不仅会发送给这个频道的所有订阅者,还会发送给所有与这个模式相匹配的模式的订阅者。

  • 例如,客户端A正在订阅频道“new.it”。
  • 客户端B正在订阅频道“new.et”。
  • 客户端C和客户端D正在订阅“new.it”频道和"new.et"频道相匹配的模式"new.[ie].t"。

向“new.it"频道发送消息"hello",那么不仅正在订阅”new.it“频道的客户端A会收到雄安熙,客户端C和D也会收到消息,因为这两个客户端正在订阅匹配"new.it"频道的"new.[ie]t"模式。

频道的订阅与退订

当一个客户端执行SUBSCRIBE命令订阅某个或者某些频道时,这个客户端与被订阅频道之间就建立了一种订阅关系。

Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channels字典里面,这个字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面记录了所有订阅这个频道的客户端:

struct redisServer {//保存所有频道的订阅关系dict *pusub_channels;
};

订阅频道

每当客户端执行SUBSCRIBE命令订阅某个或者某些频道时,服务器都会将客户端与被订阅的频道在pubsub_channels字典进行关联。
根据频道频道是否有其他订阅者,关联操作分为两种情况执行:

  • 如果频道已经有其他订阅者,那么它在pubsub_channels字典中必定有相应的订阅者链表,程序唯一要做的就是将客户端添加到订阅者链表的末尾。
  • 如果频带还未有任务订阅者,那么它必然不存在字典中,程序首先在pubsub_channels字典中为频道创建一个键,并将这个键的值设置为空链表,然后将客户都安添加到链表,成为链表的第一个元素。

退订频道

UNSUBSCRIBE命令的行为和SUBSCRIBE命令的行为正好相反,当一个客户都安退订某个或者某些频道时,服务器将从pubsub_channels中接触客户端与被退订频道之间的关联:

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

模式的订阅与退订

服务器将所有频道的订阅关系都保存在服务器状态pubsub_channels属性里面,服务器也将所有模式的订阅关系都保存在服务器状态的pubsub_patterns属性里面:

struct redisServer {//保存所有模式订阅关系list *pubsub_patterns;
};

pubsub_patterns属性是一个链表,链表中的每个节点都包含着一个pubsubPattern结构,这个结构pattern属性记录了被订阅的模式,而client属性则记录了订阅模式的客户端:

typedef struct pubsubPattern {//订阅模式的客户端redisClient *client;//被订阅的模式robj *pattern;
}pubsubPattern;

订阅模式

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

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

退订模式

模式的退订命令PUNSUBSCRIBE是PSUBSCRIBE命令的反操作:

当一个客户端退订某个或者某些模式的时候,服务器将在pubsub_patterns链表中查找并且删除那些pattern属性为退订模式,并且client属性为执行退订命令的客户端的pubsubPattern结构

发送消息

当一个Redis客户端执行PUBLISH命令将消息message发送给频道channel时候,服务器需要执行以下两个动作:

  • 将消息message发送给channel频道的所有订阅者
  • 如果有一个或者多个模式pattern与频道channel相匹配,那么将消息message发送给pattern模式的订阅者

将消息发送给频道订阅者

因为服务器状态中的所有pubsub_channel字典记录了所有频道的订阅关系,所以为了将消息发送给channel频道的所有订阅者,PUBLISH命令要做的就是在pubsub_channels字典里面找到频道channel订阅者名单(一个链表,将消息发送给名单上的所有客户端)

例如,执行以下命令:

PUBLISH ”new.it“ "hello"

那么PUBLISH命令将在pubsub_channels字典中查找键”new.it“对应的链表值,并且通过遍历链表将消息"hello"发送给订阅者

将消息发送给模式订阅者

因为服务器状态中的pubsub_patterns链表记录了所有模式的订阅关系,所以为了将消息发送给所有与channel频道相匹配的模式的订阅者,PUBLISH命令要做的就i是遍历整个链表,查找那些channel频道相匹配的模式,并将消息发送给订阅了这些模式的客户端。

小结

服务器状态在pubsub_channels字典中保存了所有频道的订阅关系:

  • SUBSCRIBE命令负责将客户端与被订阅的频道关联到这个字典中,而UNSUBSCRIBE命令则负责接触客户端和被退定的频道之间的关联
  • 服务器状态在pubsub_patterns链表保存了所有模式的订阅关系:PSUBSCRIBE命令负责将客户端和被订阅的模式记录到这个链表中,而PUNSUBSCRIBE命令则负责溢出客户端与被退订模式在链表中的记录
  • PUBLISH命令通过访问pubsub_channels字典来向频道的所有订阅者发送消息,通过访问pubsub_patterns链表来向所有匹配频道的模式的订阅者发送消息

Redis之发布与订阅相关推荐

  1. 面试被问到Redis实现发布与订阅,手摸手教

    简介 Redis发布与发布功能(Pub/Sub)是基于事件座位基本的通信机制,是目前应用比较普遍的通信模型,它的目的主要是解除消息的发布者与订阅者之间的耦合关系. Redis作为消息发布和订阅之间的服 ...

  2. Redis实现发布与订阅(转)

    简介 Redis发布与发布功能(Pub/Sub)是基于事件座位基本的通信机制,是目前应用比较普遍的通信模型,它的目的主要是解除消息的发布者与订阅者之间的耦合关系. Redis作为消息发布和订阅之间的服 ...

  3. Redis 学习笔记-NoSQL数据库 常用五大数据类型 Redis配置文件介绍 Redis的发布和订阅 Redis_事务_锁机制_秒杀 Redis应用问题解决 分布式锁

    1.NoSQL数据库 1.1 NoSQL数据库概述 NoSQL(NosQL = Not Only sQL ),意即"不仅仅是sQL",泛指非关系型的数据库.NoSQL不依赖业务逻辑 ...

  4. redis的发布和订阅功能

    原理 redis的发布和订阅是个比较高深的概念,我一开始接触的时候感觉很茫然,但是后面用了下发现还是简单的.看来还是多需要自己尝试. 其实和消息队列差不多的原理,就是一个发布的频道,所有订阅这个频道的 ...

  5. Redis——Redis 的发布和订阅

    Redis 的发布和订阅 文章目录 Redis 的发布和订阅 1.什么是发布和订阅 2.Redis 的发布和订阅 3.发布订阅命令行实现 1.什么是发布和订阅 Redis 发布订阅 (pub/sub) ...

  6. redis学习之redis的发布和订阅

    目录 什么是发布和订阅 Redis的发布和订阅 1.客户端可以订阅频道如下图 2.当给这个频道发布消息后,消息就会发送给订阅的客户端 发布订阅命令行实现 1.打开一个客户端订阅channel1 2.打 ...

  7. 【redis】发布与订阅

    发布与订阅 Redis的发布与订阅功能由PUBLISH.SUBSCRIBE.PSUBSCRIBE等命令组成.通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者(su ...

  8. Redis 的发布与订阅

    3.Redis 的发布与订阅 3.1.发布与订阅简述 Redis提供了基于"发布/订阅"模式的消息机制.此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(ch ...

  9. Redis 进阶 -- 发布与订阅

    文章目录 1. 发布与订阅 1.1 PUBLISH:向频道发送消息 1.2 SUBSCRIBE:订阅频道 1.2.1 接收频道消息 1.3 UNSUBSCRIBE:退订频道 1.4 PSUBSCRIB ...

  10. Redis 笔记系列(十一)——Redis的发布和订阅机制

    2019独角兽企业重金招聘Python工程师标准>>> 本文说的redis功能没啥大用处,大家知道有这回事情就好,我一笔带过. Redis的发布订阅 这是什么 进程间的一种消息通信模 ...

最新文章

  1. Arduino学习笔记1---开发环境搭建
  2. 粽子也内卷?2021 互联网大厂端午礼盒大盘点
  3. Java多线程的几种实现方法
  4. python struct模块的使用
  5. Linux Kernel系列三:Kernel编译和链接中的linker script语法详解
  6. 【算法】CRC 循环冗余校验
  7. atomiclong 初始化_Java并发编程【1.2时代】
  8. Golang map 三板斧第二式:注意事项
  9. xtrabackup启动过程中出现的报错
  10. Android Dialog详解
  11. Flutter 修改APP名称和logo
  12. 台式计算机不休眠,台式机如何设置不休眠
  13. Java常见的加密解密
  14. linux的各种自带库-lz -lrt -lm -lc都是什么库
  15. 如何使用IP地址链接数据库
  16. matlab中的measure,关于matlab中awgn函数中参数作用的测试
  17. change事件做延迟处理
  18. android 7.1 去除分屏功能
  19. 手把手实现andriod应用增量升级
  20. OMNeT学习之新建工程

热门文章

  1. swift iOS sceneKit 导入外部dae
  2. AI边缘计算分析与视频技术,如何助力企业安全生产智能监管?
  3. 天上掉馅饼 期望dp+状压dp
  4. 东方不败III游戏修改大师
  5. 人人视频APP突遭下架:上亿用户慌了
  6. 汽车前覆盖板高速碰撞实验
  7. 3d机器学习open3d学习教程3--点云2
  8. 韩国 kakaotalk web网页版第三方登录示例 kakaotalk网页版
  9. i.MX6ULL系统移植:Linux移植3 - make xxx_defconfig分析
  10. 下面linux程序中哪一个是调试器,【单选题】下面Linux程序中哪一个是调试器?A. vi B. gcc C. gdb D. make...