当前位置: 首页 > news >正文

RocketMQ~刷盘机制、主从复制方式、存储机制

刷盘机制

生产者发布MQ给Brocker,Brocker在存储这些数据的时候,需要进行刷盘,分为同步刷盘和异步刷盘。

在同步刷盘中需要等待一个刷盘成功的ACK,同步刷盘对MQ消息可靠性来说是一种不错的保障,但是性能上会有较大影响,一般地适用于金融等特定业务场景。

而异步刷盘往往是开启一个线程去异步地执行刷盘操作。消息刷盘采用后台异步线程提交的方式进行,降低了读写延迟,提高了MQ的性能和吞吐量,一般适用于如发验证码等对于消息保证要求不太高的业务场景。

一般地,异步刷盘只有在Broker意外宕机的时候会丢失部分数据,你可以设置Broker的参数FlushDiskType来调整你的刷盘策略(ASYNC_FLUSH或者SYNC_FLUSH)
在这里插入图片描述

同步复制和异步复制

上面的同步刷盘和异步刷盘是在单个结点层面的,而同步复制和异步复制主要是指的Borker主从模式下,主节点返回消息给客户端的时候是否需要同步从节点。

  • 同步复制:也叫"同步双写",也就是说,只有消息同步双写到主从节点上时才返回写入成功。
  • 异步复制:消息写入主节点之后就直接返回写入成功。

然而,很多事情是没有完美的方案的,就比如我们进行消息写入的节点越多就更能保证消息的可靠性,但是随之的性能也会下降,所以需要程序员根据特定业务场景去选择适应的主从复制方案。

异步同步复制策略,不仅影响消息的可靠性,还影响到了这个Brocker的可用性。

存储机制

首先想大家介绍RocketMQ消息存储架构中的三大角色: CommitLog、ConsumeQueue 和 IndexFile。

  • CommitLog:消息主体以及元数据的存储主体,存储 Producer端写入的消息主体内容,消息内容不是定长的。单个文件大小默认1G,记录了消息内容以及大小,当第一个文件写满了,消息主要是顺序写入日志文件,当文件满了,写入下一个文件。
  • ConsumeQueue:消息消费队列,引入的目的主要是提高消息消费的性能,由于RocketMQ 是基于主题 Topic的订阅模式,消息消费是针对主题进行的,如果要遍历 Commitlog文件中根据Topic检索消息是非常低效的。Consumer即可根据 ConsumeQueue 来查找待消费的消息。其中,ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量 offset,消息大小size和消息息Tag的HashCode值。consumequeue文件可以看成是基于 topic 的 commitlog索引文件
  • IndexFile:IndexFile (索引文件)提供了一种可以通过key或时间区间来查询消息的方法。

总结来说,整个消息存储的结构,最主要的就是CommitLoq和ConsumeQueue。而ConsumeQueue你可以大概理解为Topic中的队列。

RocketMQ 采用的是混合型的存储结构。即为 Broker单个实列下所有的队列共用一个日志数据文件来存储消息。有意思的是在同样高并发的 Kafka中会为每个Topic分配一个存储文件。这就有点类似于我们有一大堆书需要装上书架,RocketMQ是不分书的种类直接成批的塞上去的,而Kafka分类区域的,是将书本放入指定的。这也是和Kafka最大的区别,也是为什么Kafka建议在少Topic,单TopicQPS大的场景下使用

RocketMQ为什么要这么做呢?原因是提高数据的写入效率,不分Topic意味着我们有更大的几率获取成批的消息进行数据写入,但也会带来一个麻烦就是读取消息的时候需要遍历整个大文件,这是非常耗时的。

所以,在RocketMQ中又使用了 ConsumeQueue 作为每个队列的索引文件来提升读取消息的效率。我们可以直接根据队列的消息序号,计算出索引的全局位置,然后直接读取这条索引,再根据索引中记录的消息的全局位置,找到消息。

生产者发送消息会指定 Topic 、QueueId和具体消息内容,而在 Broker中管你是哪门子消息,他直接全部顺序存储到了CommitLog。而根据生产者指定的Topic 、 QueueId、这条消息本身在 CommitLog的偏移(offset),消息本身大小、和tag的hash值存入对应Topic的 ConsumeQueuue索引文件中。而在每个队列中都保存了Consume0ffset 即每个消费者组的消费位置,消费者拉取消息进行消费的时候只需要根据 Consume0ffset在ConsumeQueuue文件中获取下一个未被消费的消息就行了。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Nginx - 反向代理、缓存详解
  • msxml*.dll 错误 ‘80072f7d‘ 安全频道支持出错 解决方案
  • Linux网络配置和系统管理
  • 【发邮件】 在邮件中添加 (mailto:) 链接的返回电子邮件
  • 【Python】机器学习中的 K-均值聚类算法及其优缺点
  • 解决在IIS下typecho访问网址为localhost的问题
  • MySQL 系统学习系列 - SQL 语句 DQL 语句的使用(3)《MySQL系列篇-05》
  • Lua 迭代器
  • 5、指针
  • Wireshark_UDP_v7.0
  • OpenCV几何图像变换(6)计算反转仿射变换函数invertAffineTransform()的使用
  • Springboot里集成Mybatis-plus、ClickHouse
  • PsConvertToGuiThread函数调用前传
  • 架构设计(4)面向服务架构SOA与C++模拟实现
  • [数据集][目标检测]建筑工地楼层空洞检测数据集VOC+YOLO格式2588张1类别
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • CentOS从零开始部署Nodejs项目
  • conda常用的命令
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • flask接收请求并推入栈
  • IDEA常用插件整理
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Java到底能干嘛?
  • Java精华积累:初学者都应该搞懂的问题
  • JS+CSS实现数字滚动
  • js操作时间(持续更新)
  • overflow: hidden IE7无效
  • rabbitmq延迟消息示例
  • Shadow DOM 内部构造及如何构建独立组件
  • spring security oauth2 password授权模式
  • supervisor 永不挂掉的进程 安装以及使用
  • Swoft 源码剖析 - 代码自动更新机制
  • windows-nginx-https-本地配置
  • 阿里云前端周刊 - 第 26 期
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • # Apache SeaTunnel 究竟是什么?
  • ## 1.3.Git命令
  • #stm32驱动外设模块总结w5500模块
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (十一)c52学习之旅-动态数码管
  • (一)80c52学习之旅-起始篇
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转载)Linux网络编程入门
  • .net MySql
  • .net 程序发生了一个不可捕获的异常
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET和.COM和.CN域名区别
  • .net后端程序发布到nignx上,通过nginx访问
  • .NET框架设计—常被忽视的C#设计技巧