要持久化的关键数据有三种

  1. 消息;
  2. 队列,队列中存放的是消息索引信息,即消息在文件中的物理位置(messageOffset)和在队列中的逻辑位置(queueOffset)的映射信息;
  3. 队列消费进度,表示当前队列中的消息消费到第几个了;

发送消息的设计

  1. producer将消息的二进制数据发送到broker;
  2. broker做的事情:
    • 单线程持久化消息到内存映射文件;
    • 将当前消息的索引信息放入缓冲区,可以使用disruptor的ringbuffer实现,单线程写,无锁。
    • 单线程从缓冲区读取消息索引信息,并将索引信息写入内存映射文件;
    • 消息的内存映射文件、消息索引的内存映射文件都定时刷新到磁盘,比如每隔1s刷新一次,可配置;
  3. broker将当前消息的索引信息放入缓冲区后,就立即返回了,然后producer就收到了消息发送的结果;

其他说明:

  1. 因为不可能用一个文件来保存所有的消息,所以肯定是用多个文件的方式。也就是说,无论是保存消息还是保存消息索引,都用多个文件。另外,由于队列有多个,所以每个队列都对应多个内存映射文件。队列文件的目录命名规则:rootPath / topic / queueId / queue mapped files
  2. broker在将消息的索引信息放入缓冲区时,要检查缓冲区是否到达一定的水位,比如ringbuffer总大小100W个槽,假如水位是80%,那就是当现在ringbuffer中可用的槽不到20%时,应该要做流控,比如sleep 100s;理论上应该不会到达水位,因为写消息索引肯定比写消息本身要快;

消费消息的设计

  1. consumer告诉broker当前需要拉取哪个topic下的哪个队列里的第几个位置(queueOffset)开始的消息,并告诉要最多拉取多少个消息;
  2. broker根据topic和queueId找到对应的队列;
  3. 根据queueOffset从队列拿到消息在文件中的物理位置,即messageOffset;
  4. 根据messageOffset从消息的内存映射文件获取消息二进制数据;
  5. 将消息二进制数据写入临时的内存流里,该内存流里包含了所有要返回的消息;
  6. 消息拉取数量达到要求或没有新的消息可以拉取后,将内存流对应的二进制数据返回给consumer;
  7. consumer解析二进制数据,得到所有的消息对象;

broker定时清理过期的消息和消息索引

  1. 每隔10s扫描是否有过期的消息文件,过期时间可配置,比如三天;扫描时,发现文件的最后修改时间是3天前,则删除;
  2. 每隔10s扫描是否有过期的消息索引文件,判断是否过期的依据是扫描每个消息索引文件,判断该文件中的最后一个消息索引的messageOffset是否比最小的messageOffset还要小;如果小,就说明这个消息索引文件已经无意义了,可以删除;

broker启动时的逻辑

  1. 扫描磁盘上所有的消息的存储文件,为每个文件建立内存映射;
  2. 扫描磁盘上所有的队列(消息索引)的存储文件,为每个文件建立内存映射;
  3. 对每个队列,预恢复几个文件(比如最后的3个文件)的数据到内存,剩余的用到时再恢复;
  4. 同理,对于存储消息的文件,也预恢复几个(比如最后的3个文件)到内存;一般大部分消息者只要消费进度不是太慢,总是应该已经赶上了最后那三个文件了;
  5. 关于异常关闭broker时的逻辑,暂时还没想清楚,还需要再细思;

EQueue文件持久化消息关键点设计思路的更多相关文章

  1. 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路

    最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...

  2. ENode 1.0 - 消息队列的设计思路

    开源地址:https://github.com/tangxuehua/enode 上一篇文章,简单介绍了enode框架内部的整体实现思路,用到了staged event-driven architec ...

  3. enode框架step by step之消息队列的设计思路

    enode框架step by step之消息队列的设计思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by ste ...

  4. ENode 1.0 - 消息的重试机制的设计思路

    项目开源地址:https://github.com/tangxuehua/enode 上一篇文章,简单介绍了enode框架中消息队列的设计思路,本文介绍一下enode框架中关系消息的重试机制的设计思路 ...

  5. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo

    26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...

  6. EventStore的设计思路

    EventStore的设计思路 最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event ...

  7. Python 番外 消息队列设计精要

    消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的Active ...

  8. ActiveMQ学习总结(8)——消息队列设计精要

    消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一. 当今市面上有很多主流的消息中间件,如老牌的Activ ...

  9. ENode框架单台机器在处理Command时的设计思路

    设计目标 尽量快的处理命令和事件,保证吞吐量: 处理完一个命令后不需要等待命令产生的事件持久化完成就能处理下一个命令,从而保证领域内的业务逻辑处理不依赖于持久化IO,实现真正的in-memory: 保 ...

随机推荐

  1. JS核心系列:理解 new 的运行机制

    和其他高级语言一样 javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象. 但在 javascript 中,万物皆对象,为什么还要通过 ...

  2. sublime常用快捷键

    自己觉得比较实用的sublime快捷键: Ctrl + /  ---------------------注释 Ctrl + 滚动 --------------字体变大/缩小 Ctrl + N----- ...

  3. jsp中出现onclick函数提示Cannot return from outside a function or method

    在使用Myeclipse10部署完项目后,原先不出错的项目,会有红色的叉叉,JSP页面会提示onclick函数错误 Cannot return from outside a function or m ...

  4. Python应用03 使用PyQT制作视频播放器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁任何形式转载. 最近研究了Python的两个GUI包,Tkinter和PyQT.这两个GUI包的底层分别是Tcl/ ...

  5. IOS FMDB 获取数据库表和表中的数据

    ios开发中,经常会用到数据库sqlite的知识,除了增,删,改,查之外,我们说说如何获取数据库中有多少表和表相关的内容. 前言 跟数据库使用相关的一般的增删改查的语句,这里就不做解释了.在网上有很多 ...

  6. C#日志

    参考页面: http://www.yuanjiaocheng.net/Entity/first.html http://www.yuanjiaocheng.net/Entity/jieshao.htm ...

  7. MVC还是MVVM?或许VMVC更适合WinForm客户端

    最近开始重构一个稍嫌古老的C/S项目,原先采用的技术栈是『WinForm』+『WCF』+『EF』.相对于现在铺天盖地的B/S架构来说,看上去似乎和Win95一样古老,很多新入行的,可能就没有见过经典的 ...

  8. 餐饮连锁公司IT信息化解决方案一

             从餐饮企业的信息化需求来说,没有哪一种解决方案能满足所有餐饮企业的信息化建设需要.不同的餐饮业态有不同的业务流程,不同业态的信息化解决方案是目前餐饮企业信息化建设急需的,这种一站式整 ...

  9. cesium核心类Viewer简介

    1.简单描述Viewer Viewer类是cesium的核心类,是地图可视化展示的主窗口,cesium程序应用的切入口,扮演必不可少的核心角色. 官网的英文解析如下: A base widget fo ...

  10. KOTLIN开发语言文档(官方文档) -- 2.基本概念

    网页链接:https://kotlinlang.org/docs/reference/basic-types.html 2.   基本概念 2.1.  基本类型 从可以在任何变量处理调用成员函数和属性 ...