首页 > 其他 > 详细

Redis发布与订阅命令和原理

时间:2020-12-14 08:36:00      阅读:34      评论:0      收藏:0      [点我收藏+]

本篇博客是对《Redis设计与实现》的学习总结
日期:2020-12-11
Redis版本:3.0.6

发布与订阅相关命令

  1. 订阅
subscribe channel [channel ...]

订阅一个或多个频道

  1. 发布
publish channel message

向一个频道发布消息,返回向多少个客户端发送了消息

  1. 按照模式订阅
psubscribe pattern [pattern ...]

如果 publish 命令发送的频道和订阅的模式成功匹配,那么客户端就会接收到发布的消息

  1. 查看频道
pubsub channels [pattern]

返回有客户端订阅的频道,是用 pattern 参数,只返回与模式匹配的有客户端订阅的频道

  1. 查看频道的订阅数
pubsub numsub [channel ...]

返回频道和其订阅数

  1. 查看模式的订阅数
pubsub numpat

实现原理

Redis将订阅关系保存在一个字典里面(Redis的字典是用哈希表实现的,基本可以认为字典就是哈希表),其中键是字符串类型就是频道名,值是一个链表存着所有订阅了该频道的客户端指针。

技术分享图片

图一

如上图所示,有三个频道:aaa,bbb和ccc。其中client-1订阅了全部三个频道,client-2订阅了 aaa 和 bbb,client-3订阅了 aaa。其中客户端指针指向客户端状态结构,这个结构中保存着套接字描述符以及各种其他信息,Redis可以通过此结构提供的信息向客户端发送数据。

  1. 频道订阅
    当订阅一个频道的时候,只需要将客户端指针添加到该频道对应的链表的末尾即可,如果该频道还不是字典的键,那么创建键和对应的链表,并将客户端指针添加到链表末尾。比如,client-3 执行了 subscribe ccc ,那么字典结构将如下图所示:
技术分享图片

图二

  1. 退订频道
    当一个客户端使用 unsubscribe 命令时,就会将客户端指针从要退订的频道对应的列表中删除。比如,在图二基础上,client-3 执行 unsubscribe ccc,那么字典结构将由图二变为图一。如果将客户端指针删去后,频道对应的列表为空了,那么也会将频道删去。比如,在图一基础上,client-1 执行 unsubscribe ccc,那么字典结构将如下图所示:
技术分享图片

图三

  1. 查看频道
    当执行pubsub channels时,只需要遍历字典的所有键,将其返回即可。如果给了模式参数,只需要将与模式匹配的键返回即可。如果对图一结构的字典,使用pubsub channels命令,返回值将是:
1) "aaa"
2) "bbb"
3) "ccc"
  1. 查看频道的订阅数
    当执行pubsub numsub [channel ...]命令时,只需要返回频道对应的列表的长度即可,如果键值不存在返回0即可,如果对图一结构的字典,使用pubsub numsub aaa,返回值将是:
1) "aaa"
2) (integer) 3
  1. 订阅模式
    订阅模式和客户端的关系存在一个链表中,每一个节点都会保存模式字符串和客户端指针,链表结构如下图所示:
技术分享图片

图四

如果此时 client-4 执行```psubscribe c*```,那么链表结构将如下图所示:
技术分享图片

图五

  1. 模式退订
    当执行punsubscribe pattern命令时,就会将链表中模式和客户端指针都对应相等的节点删去,比如,client-3 执行punsubscribe b*,那么链表结构将如下图所示:
技术分享图片

图六

  1. 发布信息
    在发布信息的时候,需要分别将信息发送给订阅频道的客户端和订阅模式的客户端。
  • 在将信息发送给订阅频道的客户端时,只需要在字典中找到该频道对应的链表,然后将信息发送给链表中的所有客户端。
  • 在将信息发送给订阅模式的客户端时,需要遍历整个保存模式订阅的链表,如果发布的频道和模式匹配,则将其发送给这个客户端
    以图一和图五为例,如果执行命令publish bbb message,那么首先在字典中找到频道 bbb 对应的客户端链表,将其发送给 client-1,client-2,然后遍历模式链表,发现之后模式 b* 匹配,那么再将信息发送给 client-3。

补充

因为使用 redis-cli 在执行 subscribe 或者 psubscribe 命令之后,就只能接收消息而不能执行命令了,要退出也只能用 Ctrl + c,所以我暂时还不知道退订命令要如何使用,在我知道后会做补充和修正。

参考资料

  • 《Redis设计与实现》
  • 《Redis开发与运维》

Redis发布与订阅命令和原理

原文:https://www.cnblogs.com/mywuhao/p/14127213.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!