Apache RocketMQ 4.9.1 高性能优化之路(上)

简介: Apache RocketMQ 4.9.1 高性能优化之路(上)

经过社区的投票,Apache RocketMQ 秋天的第一个版本 4.9.1 如约而至,该版本中最值得关注的是高性能优化这块,针对 Broker 端的性能,特别是对小消息的生产性能进行了针对性优化,和 4.9.0 版本相比,小消息实时生产的 TPS 提升了约 28%。


这一批优化相关的 Pull Request(PR)都挂在 ISSUE2883下,分为 7 个 PR(A-G),接下来我们来看一下这一批优化的细节,大家也可以到 github 查看代码明细。


A、针对事务消息的优化



在当前的版本中,事务消息已经较为成熟,但压测的时候就会发现,默认的配置下每条消息都会打出一条日志:


log.info("Half offset {} has been committed/rolled back", i);


这肯定会影响性能,压测等大流量场景下甚至会导致灾难性影响。所以这个优化最简单,把这个日志改成 debug 就可以了。


B、消除不必要的锁



在 RocketMQ 内部,主从复制和同步刷盘都是多线程协作处理的。以主从复制为例(GroupTransferService),消息处理线程(多个)不断接收消息,产生待复制的消息,另外有一个 ServiceThread 单线程处理复制结果,可以把前者看做数据生产者,后者看做数据消费者,RocketMQ 使用了双 Buffer 来达到批量处理的目的。如下图,消费者正在处理数据的同时,生产者可以不受影响的继续添加数据,第一阶段生产者 Buffer 有 3 条数据,消费者 Buffer 有 2 条数据,由于消费者是单线程,没有别的线程跟它竞争,所以它可以批量处理这 2 条数据,完成后它会交换这两个 Buffer 的引用,于是接下来的第二阶段它又可以批量处理 3 条数据。


image.png



之前 RocketMQ 在生产者写入、交换 Buffer 引用、以及内部处理中都使用了多个重量级锁保证线程安全。但实际上只需要在生产线程写入以及交换 Buffer 引用的时候加轻量级自旋锁就可以,由于这两个操作都是非常快的,因此可以认为每次加解锁都只有 2 次 CAS 操作的开销。


除此之外,WaitNotifyObject 类也进行了优化,减少了需要进入同步代码块的次数。


image.png


RocketMQ 使用 mmap 来方法 CommitLog 文件,其中有一个好处就是 io 操作的时候少了一个内存拷贝。但实际上由于工程的复杂性,代码中仍然会存在各种各样的内存拷贝,我们优化的目标就是消除那些本来可以避免的复制。


这一次我们就在主从复制这里找到了一个优化点,有一个 ByteBuffer,要把其中一部分写到 CommitLog 里面去,原来的代码会创建一个 byte [],然后复制一遍,其实只需要传入 ByteBuffer.array() 给后续方法,然后指明要复制的起止位置就可以了。这样优化后我们还节省了这个 byte[] 的创建,原先复制 1G 的 CommitLog 就会有至少 1G 的 byte[] 对象的分配和 gc 开销,这下也省了。这次修改的部分实际上运行在 Slave 中,但在同步复制的场景下,对消息发送的响应时间还是有影响的。


image.png


从 RocketMQ4.X 开始引入了自旋锁并作为默认值,同时将参数 sendMessageThreadPoolNums(出现消息生产的线程数)改为了 1,这样处理每条消息写 CommitLog 的时候可以省下进出重量锁的开销。
不过这个地方单线程处理,任务有点重,处理消息的逻辑并不是往 CommitLog 里面一写(无法并行)就完事的,还有一些 CPU 开销比较大的工作,多线程处理比较好,经过一些实践测试,4 个线程是比较合理的数值,因此这个参数默认值改为 MIN(逻辑处理器数, 4)。


既然有 4 个线程,还用自旋锁可能就不合适了,因为拿不到锁的线程会让 CPU 白白空转。所以 useReentrantLockWhenPutMessage 参数还是改为 true 比较好。


还有个细节,endTransactionThreadPoolNums 这个参数默认设置成了 sendMessageThreadPoolNums 的至少 4 倍,以避免事务消息量特别大的场景下(比如事务消息压测),二阶段处理速度赶不上一阶段处理速度,进而导致严重的问题。


此外,对刷盘相关的参数也进行了调整。默认情况下,RocketMQ 是异步刷盘,但每次处理消息都会触发一个异步的刷盘请求。这次将 flushCommitLogTimed 这个参数改成 true,也就是定时刷盘(默认每 500ms),可以大幅降低对 IO 压力,在主从同步复制的场景下,可靠性也不会降低。


image.png


写 CommitLog 只能单线程操作,写之前要先获取一个锁,这个锁也就是影响 RocketMQ 性能最关键的一个锁。理论上这里只要往 MappedByteBuffer 写一下就好了,但实践往往要比理论复杂得多,因为各种原因,这个锁里面干的事情非常的多。


由于当前代码的复杂性,这个优化是本批次修改里面改动最大的,但它的逻辑其实很简单,就是把锁内干的事情,尽量的放到锁的外面去做,能先准备好的数据就先准备好。它包括了一下改动:


1、将 Buffer 的大部分准备工作(编码工作)放到了锁外,提前做好。


2、将 MessageId 的做成了懒初始化(放到锁外),这个消息 ID 的生成涉及很多编解码和数据复制工作,实际上性能开销相当大。


3、原来锁内用来查位点哈希表的 Key 是个拼接出来的字符串,这次也改到锁外先生成好。


4、顺便补上了之前遗漏的关于 IPv6 的处理。


5、删除了无用的代码。

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
10月前
|
消息中间件 存储 NoSQL
RocketMQ实战—6.生产优化及运维方案
本文围绕RocketMQ集群的使用与优化,详细探讨了六个关键问题。首先,介绍了如何通过ACL配置实现RocketMQ集群的权限控制,防止不同团队间误用Topic。其次,讲解了消息轨迹功能的开启与追踪流程,帮助定位和排查问题。接着,分析了百万消息积压的处理方法,包括直接丢弃、扩容消费者或通过新Topic间接扩容等策略。此外,提出了针对RocketMQ集群崩溃的金融级高可用方案,确保消息不丢失。同时,讨论了为RocketMQ增加限流功能的重要性及实现方式,以提升系统稳定性。最后,分享了从Kafka迁移到RocketMQ的双写双读方案,确保数据一致性与平稳过渡。
|
消息中间件 人工智能 Apache
Apache RocketMQ 中文社区全新升级!
RocketMQ 中文社区升级发布只是起点,我们将持续优化体验细节,推出更多功能和服务,更重要的是提供更多全面、深度、高质量的内容。
1063 125
|
消息中间件 监控 大数据
优化Apache Kafka性能:最佳实践与调优策略
【10月更文挑战第24天】作为一名已经对Apache Kafka有所了解并有实际使用经验的开发者,我深知在大数据处理和实时数据流传输中,Kafka的重要性不言而喻。然而,在面对日益增长的数据量和业务需求时,如何保证系统的高性能和稳定性成为了摆在我们面前的一个挑战。本文将从我的个人视角出发,分享一些关于如何通过合理的配置和调优来提高Kafka性能的经验和建议。
490 4
|
10月前
|
消息中间件 存储 设计模式
RocketMQ原理—5.高可用+高并发+高性能架构
本文主要从高可用架构、高并发架构、高性能架构三个方面来介绍RocketMQ的原理。
3157 21
RocketMQ原理—5.高可用+高并发+高性能架构
|
消息中间件 存储 Apache
恭喜 Apache RocketMQ、Apache Seata 荣获 2024 开源创新榜单“年度开源项目”
近日,以“新纪天工、开物焕彩——致敬开源的力量”为活动主题的“重大科技成就发布会(首场)”在国家科技传播中心成功举办,并隆重揭晓了 2024 开源创新榜单,旨在致敬中国开源力量,传播推广开源科技成就,营造中国开源创新生态。2024 年开源创新榜单由中国科协科学技术传播中心、中国计算机学会、中国通信学会、中国科学院软件研究所共同主办,中国开发者社区承办,以王怀民院士为首组建评审委员会,进行研讨评审,面向中国开源行业领域,遴选具有创新性、贡献度和影响力的开源项目、社区、应用场景与开源事件。在评审出的 10 个年度开源项目中,Apache RocketMQ、Apache Seata 成功入选。
466 111
|
消息中间件 监控 数据挖掘
基于RabbitMQ与Apache Flink构建实时分析系统
【8月更文第28天】本文将介绍如何利用RabbitMQ作为数据源,结合Apache Flink进行实时数据分析。我们将构建一个简单的实时分析系统,该系统能够接收来自不同来源的数据,对数据进行实时处理,并将结果输出到另一个队列或存储系统中。
1208 2
|
10月前
|
监控 安全 BI
优化 Apache 日志记录的 5 个最佳实践
Apache 日志记录对于维护系统运行状况和网络安全至关重要,其核心包括访问日志与错误日志的管理。通过制定合理的日志策略,如选择合适的日志格式、利用条件日志减少冗余、优化日志级别、使用取证模块提升安全性及实施日志轮换,可有效提高日志可用性并降低系统负担。此外,借助 Eventlog Analyzer 等专业工具,能够实现日志的高效收集、可视化分析与威胁检测,从而精准定位安全隐患、评估服务器性能,并满足合规需求,为强化网络安全提供有力支持。
272 0
优化 Apache 日志记录的 5 个最佳实践
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
SQL 分布式计算 NoSQL
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
223 1
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
|
SQL 存储 数据处理
兼顾高性能与低成本,浅析 Apache Doris 异步物化视图原理及典型场景
Apache Doris 物化视图进行了支持。**早期版本中,Doris 支持同步物化视图;从 2.1 版本开始,正式引入异步物化视图,[并在 3.0 版本中完善了这一功能](https://www.selectdb.com/blog/1058)。**
934 1

热门文章

最新文章

推荐镜像

更多