【腾讯云】618云聚惠,百款云产品限量抢购,1核2G云服务器首年95元 https://cloud.tencent.com/act/cps/redirect?redirect=1059&cps_key=9f7b3aa0b9ee11c8648ef8bf9d4f15a9&from=console

搜搜吧

搜搜吧 门户 教程 电脑网络 查看内容

一文带你了解 Redis 的发布与订阅的底层原理

2020-1-2 13:49| 发布者: 虚拟主机评测| 查看: 30| 评论: 0

摘要: 01、前言发布订阅系统在我们日常的工作中经常会使用到,这种场景大部分情况我们都是使用消息队列的,常用的消息队列有 Kafka,RocketMQ,RabbitMQ,每一种消息队列都有其特性。这篇文章主要是给大家介绍 Redis 的发 ...

 

01、前言

发布订阅系统在我们日常的工作中经常会使用到,这种场景大部分情况我们都是使用消息队列的,常用的消息队列有 Kafka,RocketMQ,RabbitMQ,每一种消息队列都有其特性。这篇文章主要是给大家介绍 Redis 的发布订阅系统,很多时候我们可能不需要独立部署相应的消息队列,只是简单的使用,而且数据量也不会太大,这种情况下,我们就可以使用 Redis 的 Pub/Sub 模型。

02、使用方式

2.1 发布与订阅

Redis 的发布订阅功能主要由 PUBLISH,SUBSCRIBE,PSUBSCRIBE 命令组成,一个或者多个客户端订阅某个或者多个频道,当其他客户端向该频道发送消息的时候,订阅了该频道的客户端都会收到对应的消息。

上图中有四个客户端,Client 02,Client 03,Client 04 订阅了同一个 Sport 频道(Channel),这时当 Client 01 向 Sport Channel 发送消息 “basketball” 的时候,02-04 这三个客户端都同时收到了这条消息。

整个过程的执行命令如下:

首先开四个 Redis 的客户端,然后在 Client 02,Client 03,Client 04 中输入subscribe sport 命令,表示订阅 sport 这个频道

然后在 Client 01 的客户端中输入publish sport basketball 表示向 sport 频道发送消息 "basketball"

这个时候我们在去看下 Client 02-04 的客户端,可以看到已经收到了消息了,每个订阅了这个频道的客户端都是一样的。

这里 Client 02-Client 04 三个客户端订阅了 Sport 频道,我们叫做订阅者(subscriber),Client 01 发布消息,我们叫做发布者(publisher),发送的消息就是 message。

2.2、模式订阅

前面我们看到的是一个客户端订阅了一个 Channel,事实上单个客户端也可以同时订阅多个 Channel,采用模式匹配的方式,一个客户端可以同时订阅多个 Channel。

如上图 Client 05 通过命令subscribe run 订阅了 run 频道,Client 06 通过命令psubscribe run* 订阅了 run* 匹配的频道。当 Client 07 向 run 频道发送消息 666 的时候,05 和 06 两个客户端都收到消息了;接下来 Client 07 向 run1 和 run_sport 两个频道发送消息的时候,Client 06 依旧可以收到消息,而 Client 05 就收不到了消息了。

Client 05 订阅run 频道和接收到消息:

Client 06 订阅run* 频道和接收到消息:

Client 07 向多个频道发送消息:

通过上面的案例,我们学会了一个客户端可以订阅单个或者多个频道,分别通过subscribe,psubscribe 命令,客户端可以通过 publish 发送相应的消息。

在命令行中我们可以用 Ctrl + C 来取消相关订阅,对应的命令时 unsubscribe channelName。

03、Pub/Sub 底层存储结构

3.1、订阅 Channel

在 Redis 的底层结构中,客户端和频道的订阅关系是通过一个字典加链表的结构保存的,形式如下:

在 Redis 的底层结构中,Redis 服务器结构体中定义了一个 pubsub_channels 字典

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

在这个字典中,key 代表的是频道名称,value 是一个链表,这个链表里面存放的是所有订阅这个频道的客户端。

所以当有客户端执行订阅频道的动作的时候,服务器就会将客户端与被订阅的频道在 pubsub_channels 字典中进行关联。

这个时候有两种情况:

该渠道是首次被订阅:首次被订阅说明在字典中并不存在该渠道的信息,那么程序首先要创建一个对应的 key,并且要赋值一个空链表,然后将对应的客户端加入到链表中。此时链表只有一个元素。


搜搜吧社区温馨提示:
搜搜吧(www.sosoba.org)十分重视网络版权及其他知识产权的保护,针对网络侵权采取如下版权政策:
1、本站有理由相信网友侵犯任何人的版权或作品,(图文,文字,下载,视频,非法传播),本站有权不事先通知即删除涉嫌侵权的作品和内容
2、本站将采取必要的网络技术手段,确认为侵权作品或内容的用户有权进行警告、屏蔽、删除的行为,尽可能的防止侵权行为的发生
3、搜搜吧影视资源均收集自互联网,没有提供影片资源存储,也未参与录制上传,若本站收录的资源涉及您的版权或知识产权或其他利益,我们会立即删除
4、搜搜吧,删帖,投诉,举报,侵权,若本站侵犯您的权益,附上身份及权利证明,请直接发送邮件到 kefu-sosoba@qq.com 我们将在一个工作日内删除
12下一页

鲜花

握手

雷人

路过

鸡蛋

最新评论

资讯分类

推荐图文

文章排行

Powered by www.sosoba.org Copyright © 2013-2020 搜搜吧社区 小黑屋|手机版|地图|关于我们|腾讯云代金券|帮助中心|公共DNS|搜搜吧
广告服务/项目合作: kefu-sosoba@qq.com  侵权举报邮箱: kefu-sosoba@qq.com  搜搜吧建站时间:创建于2013年07月23日
免责声明:本站所有的内容均来自互联网以及第三方作者自由发布,版权归原作者版权所有,搜搜吧不承担任何的法律责任,若有侵权请来信告知,我们立即删除!

GMT+8, 2020-5-25 16:44 , Processed in 1.126362 second(s), 10 queries , MemCache On.

返回顶部