EQueue文件持久化消息关键点设计思路
要持久化的关键数据有三种
- 消息;
- 队列,队列中存放的是消息索引信息,即消息在文件中的物理位置(messageOffset)和在队列中的逻辑位置(queueOffset)的映射信息;
- 队列消费进度,表示当前队列中的消息消费到第几个了;
发送消息的设计
- producer将消息的二进制数据发送到broker;
- broker做的事情:
- 单线程持久化消息到内存映射文件;
- 将当前消息的索引信息放入缓冲区,可以使用disruptor的ringbuffer实现,单线程写,无锁。
- 单线程从缓冲区读取消息索引信息,并将索引信息写入内存映射文件;
- 消息的内存映射文件、消息索引的内存映射文件都定时刷新到磁盘,比如每隔1s刷新一次,可配置;
- broker将当前消息的索引信息放入缓冲区后,就立即返回了,然后producer就收到了消息发送的结果;
其他说明:
- 因为不可能用一个文件来保存所有的消息,所以肯定是用多个文件的方式。也就是说,无论是保存消息还是保存消息索引,都用多个文件。另外,由于队列有多个,所以每个队列都对应多个内存映射文件。队列文件的目录命名规则:rootPath / topic / queueId / queue mapped files
- broker在将消息的索引信息放入缓冲区时,要检查缓冲区是否到达一定的水位,比如ringbuffer总大小100W个槽,假如水位是80%,那就是当现在ringbuffer中可用的槽不到20%时,应该要做流控,比如sleep 100s;理论上应该不会到达水位,因为写消息索引肯定比写消息本身要快;
消费消息的设计
- consumer告诉broker当前需要拉取哪个topic下的哪个队列里的第几个位置(queueOffset)开始的消息,并告诉要最多拉取多少个消息;
- broker根据topic和queueId找到对应的队列;
- 根据queueOffset从队列拿到消息在文件中的物理位置,即messageOffset;
- 根据messageOffset从消息的内存映射文件获取消息二进制数据;
- 将消息二进制数据写入临时的内存流里,该内存流里包含了所有要返回的消息;
- 消息拉取数量达到要求或没有新的消息可以拉取后,将内存流对应的二进制数据返回给consumer;
- consumer解析二进制数据,得到所有的消息对象;
broker定时清理过期的消息和消息索引
- 每隔10s扫描是否有过期的消息文件,过期时间可配置,比如三天;扫描时,发现文件的最后修改时间是3天前,则删除;
- 每隔10s扫描是否有过期的消息索引文件,判断是否过期的依据是扫描每个消息索引文件,判断该文件中的最后一个消息索引的messageOffset是否比最小的messageOffset还要小;如果小,就说明这个消息索引文件已经无意义了,可以删除;
broker启动时的逻辑
- 扫描磁盘上所有的消息的存储文件,为每个文件建立内存映射;
- 扫描磁盘上所有的队列(消息索引)的存储文件,为每个文件建立内存映射;
- 对每个队列,预恢复几个文件(比如最后的3个文件)的数据到内存,剩余的用到时再恢复;
- 同理,对于存储消息的文件,也预恢复几个(比如最后的3个文件)到内存;一般大部分消息者只要消费进度不是太慢,总是应该已经赶上了最后那三个文件了;
- 关于异常关闭broker时的逻辑,暂时还没想清楚,还需要再细思;
EQueue文件持久化消息关键点设计思路的更多相关文章
- 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路
最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...
- ENode 1.0 - 消息队列的设计思路
开源地址:https://github.com/tangxuehua/enode 上一篇文章,简单介绍了enode框架内部的整体实现思路,用到了staged event-driven architec ...
- enode框架step by step之消息队列的设计思路
enode框架step by step之消息队列的设计思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by ste ...
- ENode 1.0 - 消息的重试机制的设计思路
项目开源地址:https://github.com/tangxuehua/enode 上一篇文章,简单介绍了enode框架中消息队列的设计思路,本文介绍一下enode框架中关系消息的重试机制的设计思路 ...
- HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo
26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...
- EventStore的设计思路
EventStore的设计思路 最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event ...
- Python 番外 消息队列设计精要
消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的Active ...
- ActiveMQ学习总结(8)——消息队列设计精要
消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一. 当今市面上有很多主流的消息中间件,如老牌的Activ ...
- ENode框架单台机器在处理Command时的设计思路
设计目标 尽量快的处理命令和事件,保证吞吐量: 处理完一个命令后不需要等待命令产生的事件持久化完成就能处理下一个命令,从而保证领域内的业务逻辑处理不依赖于持久化IO,实现真正的in-memory: 保 ...
随机推荐
- 百度推出新技术 MIP,网页加载更快,广告呢?
我们在2016年年初推出了MIP,帮助移动页面加速(原理).内测数据表明,MIP页面在1s内加载完成.现在已经有十多家网站加入MIP项目,有更多的网站正在加入中.在我们收到的反馈中,大部分都提到了广告 ...
- 关于这段时间学习 EntityFramework的 一点感悟
Ado.Net,用了N多年,Entity Framework也关注了很多年. 每当项目转型的时候,就花费大巴的时间,学习一番,潮流的东西. 这个Orm很多,这个EF很火,这么多年了,我还是不敢用,虽然 ...
- android键盘
在应用的开发过程中有不少的情况下会用到自定义键盘,例如支付宝的支付密码的输入,以及类似的场景.android系统给开发者们提供了系统键盘,KeyboardView,其实并不复杂,只是有些开发者不知道罢 ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- 120项改进:开源超级爬虫Hawk 2.0 重磅发布!
沙漠君在历时半年,修改无数bug,更新一票新功能后,在今天隆重推出最新改进的超级爬虫Hawk 2.0! 啥?你不知道Hawk干吗用的? 这是采集数据的挖掘机,网络猎杀的重狙!半年多以前,沙漠君写了一篇 ...
- Jquery(1)
鼠标点击事件: <input type="button" value="测试" onclick="test()" /> < ...
- Nested Loops join时显示no join predicate原因分析以及解决办法
本文出处:http://www.cnblogs.com/wy123/p/6238844.html 最近遇到一个存储过程在某些特殊的情况下,效率极其低效, 至于底下到什么程度我现在都没有一个确切的数据, ...
- YII 2.x 模板文件的 beginBlock、beginContent、beginCache
echo '-----------beginBlock--------------------- <br />'; $this->beginBlock('block1', false ...
- 打破陈规抓痛点,H3 BPM10.0挑战不可能
高效益意味着相似的运营活动比竞争对手做得更好,而战略定位则意味着企业在运营活动中有区别于竞争对手的实施方式,即差异化竞争.在新经济体下,面对社会的变革.市场的竞争环境.不断攀升的成本压力,几乎没有企业 ...
- React Native Android gradle下载慢问题解决
很多人会遇到 初次运行 react-native run android的时候 gradle下载极慢,甚至会失败的问题 如下图 实际上这个问题好解决的 首先 把对应版本的gradle下载到本地任意一个 ...