Redis订阅与发布
发布与订阅模型在许多编程语言中都有实现,也就是我们经常说的设计模式中的一种--观察者模式。在一些应用场合,例如发送方并不是以固定频率发送消息,如果接收方频繁去咨询发送方,这种操作无疑是很麻烦并且不友好的。
举个生活的例子,一个喜欢购买鲜牛奶的人,需要每天在上班的时候/下班的时候都专门去牛奶店购买鲜牛奶,但不一定每天去到那里都刚好有自己喜欢的那一种牛奶,这个时候,这个人跑老远的距离都白费了。但如果这个人去牛奶店一次性订阅了一个月的某种牛奶,那么他就不用担忧今天是否能买到鲜牛奶了,只要送奶员把牛奶送到他家楼下的箱子里面就行。
而订阅发布模型与这个例子有点类似,订阅者只要订阅注册某个频道就可以“高枕无忧”了,当有消息发送过来的时候,会通过订阅的频道接收。优势在于把耦合点独立分离处理,作为发布方和接收方的中介,实现了发布方和接收方的隔离,
订阅与发布系统是Redis的一个高级属性,多个客户端可以同时订阅同一个频道,类似广播的机制。所不同的是,一个客户端可以同时订阅多个频道。
样例图:

Redis订阅发布系统,服务器在背后的工作:
服务器中维护着一个pubsub_channels字典,所有的频道和订阅关系都存储在这里。字典的键为频道的名称,而值为订阅频道的客户端链表。
1. 当有新的客户端订阅某个频道时,会发生两种情况中的一种:
1)如果频道已经存在,则新的客户端会添加到pubsub_channels对应频道的链表末尾
2)如果频道原本不存在,则会为频道创建一个键,该客户端成为链表的第一个元素
2. 当一个客户端退订一个频道的时候:
pubsub_channels对应键的链表会删除该客户端
3. 发送信息
服务器会遍历pubsub_channels中对应键的链表,向每一个客户端发送信息
服务器还维护着一个pubsub_patterns链表,链表的pattern属性记录了被订阅的模式,而client属性记录了订阅模式的客户端
1. 当有新的客户端订阅某个模式的时,会进行如下步骤:
1)创建一个链表节点,pattern属性记录订阅的模式,client记录订阅模式的客户端
2)将这个链表节点添加到pubsub_patterns链表中
2. 当一个客户端退订某一个模式的时候:
服务器遍历pubsob_patterns找到对应的pattern同时也是对应该client客户端的节点,将改节点删除
3. 发送信息
服务器遍历pubsub_channels,查找与channels频道相匹配的模式麻将消息发送给订阅了这些模式的客户端。
Redis订阅系统的优势:
1. 当一个客户端向频道发送一个信息,订阅了同一个频道/模式的多个客户端可以同时接收到信息,类似广播的机制。
2. 便于Sentinel哨兵与服务器间的通信并进行监控
1. 订阅频道
命令格式:
SUSCRIBE channel1 [channel2] [channel3]
例如(同时订阅两个频道):
redis> subscribe local_system remote_system
Reading messages... (press Ctrl-C to quit)
1) "subscribe" # 返回值的类型:显示订阅成功
2) "local_system" # 订阅的频道名字
3)"remote _system "
4) (integer) 2 # 目前已订阅的频道数量
订阅和接收者:

发送者:

注意:客户端一点与某个频道建立连接就不能进行其他操作,一旦客户端退出连接,订阅的频道自动会断开。
2. 订阅模式
PSUBSCRIBE pattern1 [pattern2] [pattern3]
pattern可以用符号*进行模糊匹配,例如:
remo* #匹配以remo开头的模式
*system #匹配以system结尾的模式
例如:
客户端1

客户端2

注意:返回的integer为1是指匹配了一个模式,实际上是匹配了两个频道。
发布信息命令:

客户端:

3. 取消订阅:
命令:
1)取消订阅频道
UNSUBSCRIBE channel1 [channel2]
2)取消订阅模式
PUNSUBSCRIBE [pattern [pattern …]]
由于在客户端界面无法实现,这里就不展示了。而在编程过程中是可以实现的。
关于python中的编程,可以看看这篇文章:
http://www.cnblogs.com/anpengapple/p/7027979.html
4. 发布消息
命令:
PUBLISH channel message
向一个频道发送信息,所有订阅这个频道的客户端都会接收到信息
5. 查看已有的频道
命令:
PUBSUB subcommand [argument [argument ...]]
subcommand子命令:
1)PUBSUB CHANNELS [pattern]
列出当前的活跃频道
如果给定pattern参数,则会返回服务器当前被订阅的频道中与pattern模式相匹配的频道
2)PUBSUB NUMSUB [channel-1 … channel-N]
返回给定频道的订阅者数量, 订阅模式的客户端不计算在内

因为有一个是匹配模式,所以返回的interger值为1
3)PUBSUB NUMPAT
返回订阅模式的数量

Sentinel哨兵中的应用:
Sentinel服务器与Master服务器/Slave服务器之间的订阅发布系统是Sentinl监控过程的一个重要环节,通过订阅发布系统达到监控服务器状态的作用。其运行原理与上面的客户端服务器之间的订阅机制无太大区别,都是基于网络连接的数据传输。Sentinel之间的通信也是通过Sentinel与服务武器间的这个订阅发布系统实现的,一个Sentinel通过服务器的频道发送信息,其他Sentinel就会接收到。
参考文章:
http://www.cnblogs.com/anpengapple/p/7027979.html
《redis设计与实现》
Redis订阅与发布的更多相关文章
- Redis订阅和发布模式和Redis事务
-------------------Redis订阅和发布模式------------------- 1.概念 Redis 发布订阅(pub/sub)是一种消息通信模式: 发送者(pu ...
- redis订阅与发布系统
一.概述 1.redis通过publish.subscribe等命令实现了订阅与发布模式. 2.这个功能提供两种信息机制,分别是订阅/发布到频道和订阅/发布到模式. 二.频道的订阅与信息发送 1.re ...
- redis 订阅与发布
PUBLISH,SUBSCRIBE,等命令实现订阅与发布 订阅/发布到频道 订阅/发布到模式 频道的订阅与信息发送 订阅subscribe,可以让客户端订阅任意数量的频道, 每当有新信息发送到 ...
- redis订阅与发布(把redis作为消息中间件)
订阅频道127.0.0.1:6379> subscribe chat1Reading messages... (press Ctrl-C to quit)1) "subscribe&q ...
- PHP swoole实现redis订阅和发布
前戏:实现用户下单,服务器通知后台接收订单...类似美团外卖 1.首先要实现一个订阅程序 $result = $client->connect('127.0.0.1', 6379, functi ...
- 上下文管理、线程池、redis订阅和发布
一:上下文管理: 对于一些对象在使用之后,需要关闭操作的.比如说:socket.mysql数据库连接.文件句柄等. 都可以用上下文来管理. 语法结构: Typical usage: @contextm ...
- Redis 订阅发布 - Jedis实现
Redis 订阅发布 - Jedis实现 我想到使用Redis的订阅发布模式是用来解决推送问题的-. 对于概念性的叙述,多多少少还是要提一下的: 什么是Redis发布订阅?Redis发布订阅是一种 ...
- 15天玩转redis —— 第九篇 发布/订阅模式
本系列已经过半了,这一篇我们来看看redis好玩的发布订阅模式,其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果 ...
- ServiceStack.Redis订阅发布服务的调用(Z)
1.Redis订阅发布介绍Redis订阅发布是一种消息通信模式:发布者(publisher)发送消息,订阅者(Subscriber)接受消息.类似于设计模式中的观察者模式.发布者和订阅者之间使用频 ...
随机推荐
- php 168任意代码执行漏洞之php的Complex (curly) syntax
今天了解了php 168的任意代码执行漏洞,Poc: http://192.168.6.128/pentest/cms/php168/member/post.php?only=1&showHt ...
- Java 生成 JNI 头文件
[参考文章]:javah javac 命令行生成native的方法教程 [参考文章]:用javah 导出类的头文件, 常见的错误及正确的使用方法 项目需要调用 C++动态库,由于项目包结构发生变化,需 ...
- 我的.gitignore下配置。存在这里一下。日后有空研究研究!
.DS_Storenode_modules/dist/yxxt/npm-debug.log*yarn-debug.log*yarn-error.log* # Editor directories an ...
- 【纯·技术干货】更 App 化的小程序开发
2018 年 10 月13 日,由又拍云和知晓云联合主办的 Open Talk 丨2018 小程序开发者沙龙系列活动广州站拉开帷幕,糗事百科前端负责人宋航在沙龙上做了<更App化的小程序开发&g ...
- Elasticsearch Document
1. 基本概念回顾 1.1. Node 节点是一个服务器,它是集群的一部分,存储数据,并参与集群的索引和搜索功能 节点有一个名称标识,该名称在缺省情况下是在启动时分配给节点的随机全局惟一标识符(U ...
- DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)
本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...
- 设计模式总结篇系列:代理模式(Proxy)
时代在发展,我们发现,现在不少明星都开始进行微访谈之类的,有越来越多的参与捐赠等.新的一天开始了,首先看下新的一天的日程安排: interface Schedule{ public void weiT ...
- SmartSql = Dapper + MyBatis + Cache(Memory | Redis) + ZooKeeper + R/W Splitting + ......
SmartSql Why 拥抱 跨平台 DotNet Core,是时候了. 高性能.高生产力,超轻量级的ORM.156kb (Dapper:168kb) So SmartSql TargetFrame ...
- 微服务浪潮中,程序猿如何让自己 Be Cloud Native
前言 CNCF 与 Cloud Native 这两个技术词汇最近频频走进了程序员的视野,一切和他能搭上边的软件意味着标准.开放.时尚,也更能俘获技术哥哥们的心:这篇文章不想去带大家重温这个词汇后面的软 ...
- [十五]javaIO之SequenceInputStream
功能简介 SequenceInputStream 合并流 顾名思义,就是可以吧两个流合并起来 他并没有很复杂,单纯的很,仅仅实现了InputStream 他拥有两个构造方法把两个InputS ...