发布/订阅的一些理解
1. 发布/订阅
发布/订阅(Publish/subscribe 或pubsub)是一种消息范式,消息的发送者(发布者)不是计划发送其消息给特定的接收者(订阅者)。而是发布的消息分为不同的类别,而不需要知道什么样的订阅者订阅。订阅者对一个或多个类别表达兴趣,于是只接收感兴趣的消息,而不需要知道什么样的发布者发布的消息。 这种发布者和订阅者的解耦可以允许更好的可扩展性和更为动态的网络拓扑。
2. 数据结构
redis里面发布订阅相对来说是独立的一个模块,代码也比较简单。 先看数据结构定义。
struct redisServer { dict *pubsub_channels; //订阅频道哈希表 list *pubsub_patterns; //订阅模式链表
}; /* * 记录订阅模式的结构 */
typedef struct pubsubPattern { // 订阅模式的客户端 redisClient *client; // 被订阅的模式 robj *pattern;
} pubsubPattern; typedef struct redisClient { dict *pubsub_channels; //这个字典记录了客户端所有订阅的频道 list *pubsub_patterns; //这个链表记录了客户端所有订阅的模式
} redisClient; 可以看到服务端和客户端都记录了订阅的频道、模式。 然后看一下订阅频道和订阅模式的代码 pubsub.c 中
int pubsubSubscribeChannel(redisClient *c, robj *channel) { dictEntry *de; if (dictAdd(c->pubsub_channels,channel,NULL) == DICT_OK) { //首先加入客户端的哈希表里 de = dictFind(server.pubsub_channels,channel); //找服务端的哈希表 if (de == NULL) { clients = listCreate(); dictAdd(server.pubsub_channels,channel,clients); incrRefCount(channel); } else { clients = dictGetVal(de); } // 将客户端添加到链表的末尾 listAddNodeTail(clients,c); }
} int pubsubSubscribePattern(redisClient *c, robj *pattern) { if (listSearchKey(c->pubsub_patterns,pattern) == NULL) { pubsubPattern *pat; // 将 pattern 添加到客户端的链表中 listAddNodeTail(c->pubsub_patterns,pattern); // 创建并设置新的 pubsubPattern 结构 pat = zmalloc(sizeof(*pat)); pat->pattern = getDecodedObject(pattern); pat->client = c; // 将 pattern 添加到服务端的链表中 listAddNodeTail(server.pubsub_patterns,pat); }
}
代码是自解释的,清晰明了。
3. 性能问题疑惑
3.1 关于退订所有消息
pubsubUnsubscribeAllChannels
pubsubUnsubscribeAllPatterns
这里用了一个迭代来遍历哈希表,但是迭代里面又重新用key来查哈希表,这个其实有性能问题。这个问题和java里面的iterate map一样,是个经常会犯的错误。
3.2 订阅模式只是用了一个链表,没有用哈希表,如果模式多了性能会有大问题
可能订阅模式和订阅频道不会很多,所以这里的编码显得不那么精雕细刻。当然这部分代码改起来也是很简单的,如果发现性能问题了随时可以改。
4. 模式匹配
util.c里面自己实现了一个glob匹配,又不得不惊叹用C语言编程太亲力亲为了。
/* Glob-style pattern matching. */
int stringmatchlen(const char *pattern, int patternLen, const char *string, int stringLen, int nocase)
{
}
发布/订阅的一些理解相关推荐
- JavaScript中发布/订阅模式的理解
订阅发布模式的介绍 发布订阅模式,它定义了一种一对多的关系,可以使多个观察者对象对一个主题对象进行监听,当这个主题对象发生改变时,依赖的所有对象都会被通知到. 在生活中我们常常遇到这样一种情况,我们在 ...
- 不好意思,观察者模式跟发布订阅模式就是不一样
一.前言 一天,小猪佩奇去了一家西餐厅,点了一份西冷牛扒,还叫了圣女果.后来服务员上了一碟番茄:佩奇小姐,这是你的「圣女果」.佩奇猪一眼就看出了猫腻:这tm是番茄,不是圣女果啊!于是就跟服务员理论起来 ...
- js观察者模式和发布订阅者模式
一.观察者模式的理解 观察者模式:一个对象(称为subject)维持一系列依赖于它的对象(称为observer),将有关状态的任何变更自动通知给它们(观察者). 二.发布/订阅模式的理解 发布/订阅模 ...
- 分布式通信:发布订阅
分布式通信:发布订阅 前言 什么是发布订阅? 发布订阅的基本工作原理 点对点模式 发布订阅模式. Kafka 发布订阅原理及工作机制 分区和消费组的原理和作用 Broker Consumer 发布订阅 ...
- 基于Redis的incr、发布订阅防并发和setnx、轮询防并发的理解
先上代码: 1.incr.发布订阅防并发 package com.xxx.epps.sfeicuss.common.anticoncurrency;import com.xxx.epps.sfeicu ...
- 深入理解观察者模式与发布订阅模式
观察者模式与发布订阅模式区别 (全文很长,认真读完相信你会有所收获) 纸上得来终觉浅 观察者模式与发布订阅模式区别 抽象模型 观察者模式 发布-订阅模式 结论 困惑 发布订阅模式?? jQuery的发 ...
- Javascript中理解发布--订阅模式
Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...
- 深入理解分布式技术 - 结合RocketMQ和Kafka理解MQ的两种经典模式_P2P模式和发布订阅模式
文章目录 规范概述 实现标准: AMQP VS JMS 基础模型 点对点 发布订阅 Kafka 的消费模式 RocketMQ 的消费模式 RocketMQ 的 集群消费 RocketMQ 的 广播消费 ...
- SQL SERVER 2008 利用发布订阅方式实现数据库同步
数据库同步方式有很多种,这里以SQL Server 2008 为例利用数据库发布和订阅的方式来演示数据库的同步技术.由于就有一台计算机,只能在同一个服务器下两个不同的数据库之间进行数据同步进行演示. ...
最新文章
- Python 之 Matplotlib (四)图例
- Hibernate搭建成功!(源码)
- 小工匠聊架构 - 分布式缓存技术
- 循环取矩阵的某行_1.2 震惊! 某大二本科生写的矩阵乘法吊打Mathematica-线性代数库BLAS-矩阵 (上)...
- 用 PS 调整服务器时间
- 上海消保委评饿了么“多等5分钟”功能:逻辑上有问题
- Spring-IOC之BeanDefinitionHolder
- 检查和变异可查询表达式树
- Window入侵排查
- js实现快速排序(in-place)简述
- 课程设计C语言歌手,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
- Harris角点检测原理分析
- Android游戏开发LoneBall小游戏
- 常见计算机英语词汇翻译,常见计算机英语词汇翻译_0.doc
- php淘口令,淘口令使用说明
- HTML CSS游戏官网网页模板——卡通的萌王游戏网页(13个页面)
- easyExcel 复杂表头 动态表头
- http://www.sciencedirect.com/ 外文文献免费全文下载方法
- 分享简单的记账方法,轻松搜索账目查看
- leaflet maxZoom突破18