RocketMQ高可用探究:消息存储技术
RocketMQ是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ的特点是纯JAVA实现、集群和HA实现相对简单、在发生宕机和其它故障时消息丢失率更低,具有良好的高可用架构及稳定性。其发展的迭代历史如下图所示,从2007年至今已发展超过10年。
图1:RocketMQ迭代历史
1 消息存储架构
图2:RocketMQ消息存储架构
RocketMQ的消息存储架构如上图所示,可以看到主要由三个跟消息存储相关的文件构成。
- CommitLog:消息及元数据的存储主体。消息内容不是定长的,同时单个文件大小默认1G,文件名长度为20位,左边补零,剩余为起始偏移量。比如00000000000000000000代表了第一个文件,起始偏移量为0,文件大小为1G=1073741824;当第一个文件写满了,第二个文件为00000000001073741824,起始偏移量为1073741824,以此类推。消息主要是顺序写入日志文件,当第一个文件满了,再写入下一个文件。
- ConsumeQueue:消息消费队列。RocketMQ是基于主题topic的订阅模式,消息消费是针对主题进行的,如果要根据topic在commitlog文件中进行检索消息,效率将会非常低效。ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset、消息大小size和消息Tag的HashCode值。所以ConsumeQueue文件可以看成是基于topic的CommitLog索引文件。ConsumeQueue文件夹的组织方式如下:topic/queue/file三层组织结构。而ConsumeQueue存储路径为:$HOME/store/consumequeue/{topic}/{queueId}/{fileName}。与Commitlog一样,ConsumeQueue文件采取了定长设计,单个文件由30W个条目组成,每一个条目共20个字节,分别为8字节的CommitLog物理偏移量、4字节的消息长度、8字节tag hashcode,Comsumer可以像数组一样随机访问每一个条目,每个ConsumeQueue文件大小约5.72M。
- IndexFile:IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。Index文件的存储位置是:$HOME /store/index${fileName},文件名fileName是以创建时的时间戳命名的,固定的单个IndexFile文件大小约为400M,一个IndexFile可以保存2000W个索引。
2 页缓存与内存映射
页缓存(PageCache)是OS对文件的缓存,用于加速对文件的读写。一般来说,程序对文件进行顺序读写的速度几乎接近于内存的读写速度,主要原因就是由于OS使用PageCache机制对读写访问操作进行了性能优化,将一部分的内存用作PageCache。对于数据的写入,OS会先写入至Cache内,随后通过异步的方式由pdflush内核线程将Cache内的数据刷盘至物理磁盘上。对于数据的读取,如果一次读取文件时出现未命中PageCache的情况,OS从物理磁盘上访问读取文件的同时,会顺序对其他相邻块的数据文件进行预读取。
在RocketMQ中,ConsumeQueue逻辑消费队列存储的数据较少,并且是顺序读取,在page cache机制的预读取作用下,Consume Queue文件的读性能几乎接近读内存,即使在有消息堆积情况下也不会影响性能。而对于CommitLog消息存储的日志数据文件来说,读取消息内容时会产生较多的随机访问读取,严重影响性能。如果选择合适的系统IO调度算法,比如设置调度算法为“Deadline”(此时块存储采用SSD的话),随机读的性能也会有所提升。
另外,RocketMQ主要通过MappedByteBuffer对文件进行读写操作。其中,利用了NIO中的FileChannel模型将磁盘上的物理文件直接映射到用户态的内存地址中(这种Mmap的方式减少了传统IO将磁盘文件数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间来回进行拷贝的性能开销),将对文件的操作转化为直接对内存地址进行操作,从而极大地提高了文件的读写效率(正因为需要使用内存映射机制,故RocketMQ的文件存储都使用定长结构来存储,方便一次将整个文件映射至内存)。
3 消息刷盘
图3:消息刷盘机制
- 同步刷盘:如上图所示,当消息真正持久化至磁盘后,RocketMQ的Broker端才会真正返回给Producer端一个成功的ACK响应。同步刷盘对MQ消息可靠性来说是一种不错的保障,但是性能上会有较大影响,一般适用于金融业务应用。
- 异步刷盘:能够充分利用OS的PageCache的优势,只要消息写入PageCache即可将成功的ACK返回给Producer端。消息刷盘采用后台异步线程提交的方式进行,降低了读写延迟,提高了MQ的性能和吞吐量。
高鑫
阿里云智能GTS-SRE团队高级技术支持工程师
多年云计算、金融行业应用运维工作经验,银行核心应用运维架构设计与应用维护。专注中间件及数据库技术,现就职于阿里云智能GTS-SRE团队,主要负责中间件领域客户技术支持工作。
我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring IOC 知识点总结,写得太好了!
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 广义的 IOC 在这之前,我们先记住一句话。好莱坞原则:Don’t call me, we will call you. 即“不用打电话过来,我们会打给你”。控制反转(Inversion of Control,简称 IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称 DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。两种实现:依赖查找(DL)和依赖注入(DI)。IOC 和 DI 、DL 的关系: DI(Dependency Injection)是 Spring 使用的方式,容器负责组件的装配。 DL(Dependency Lookup)已经被抛弃。 IOC 容器的原理 IOC 容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。 原理就是通过 ...
- 下一篇
全面升级:EDAS 全新设计控制台概览页,并新增、优化了多个功能点
近日,阿里云企业级分布式应用服务 EDAS 发布升级通告,全新设计控制台概览页,并新增、优化了多个功能点,包括: 全新概览页:根据最新的产品能力,全新设计了概览页面。在概览页可以清晰展示托管的应用数、集群数和微服务数,此外还可展示常用应用和最新的变更单等信息。 日志能力优化:ECS集群和容器服务K8s集群中的应用的日志管理能力进一步优化,您可一键添加日志文件在线查看,并且无需重新部署应用即可接入日志服务SLS(Log Service),在接入SLS时可自定义Logstore命名来提高可读性。 ECS集群中部署的应用的日志管理能力请参见日志管理。 容器服务K8s集群中部署的应用的日志管理能力请参见日志目录。 查看配置和工作负载信息:容器服务K8s集群中的应用的基本信息页面新增一键只读查看应用的部署配置信息,展示了应用的工作负载(Deployment和Pod等)信息。相关文档请参见查看应用总览。 安全沙箱容器支持:在容器服务K8s集群中的创建应用和部署应用时,支持按需选择安全沙箱容器类型为Docker或安全沙箱容器。相关文档请参见创建容器服务K8s应用。 多可用区部署:在容器服务K8s集群...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果