快手 RocketMQ 高性能实践

本文涉及的产品
云原生网关 MSE Higress,422元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 快手会定期对 RocketMQ 进行升级。2022年春节,我们大胆使用了尚未正式发布的 RocketMQ 4.9.3-SNAPSHOT 版本,平稳度过了快手一年中最重要的活动,这也证实了社区版本 RocketMQ 的兼容性和稳定性。

1.png

本文作者:黄理,快手在线消息系统负责人。


快手对于 RocketMQ 社区版本的优化一般为在其外层进行能力的构建,而不是对其内部进行大改动,因为内部大改不利于后期的版本升级。即使对内部 RocketMQ 进行了修改,我们也会尽量通过 PR 将新特性回馈到社区。


快手会定期对 RocketMQ 进行升级。2022年春节,我们大胆使用了尚未正式发布的 RocketMQ 4.9.3-SNAPSHOT 版本,平稳度过了快手一年中最重要的活动,这也证实了社区版本 RocketMQ 的兼容性和稳定性。


应用篇


2.png


RocketMQ 进入快手两年内,从 0 发展到每天数千亿消息级别。快手是 RocketMQ 社区版本的事务消息最早的大规模用户,目前每天有百亿以上的事务消息和定时消息,实现了跨 IDC的自动负载均衡以及容灾,实现了多级泳道(项目)互不干扰,多个项目可同时开发,以及可回落。


3.png


RocketMQ的落地方式一般为两种。


方式一:在开源软件的基础上进行修改,能够快速轻松地实现需要的功能,但后续升级存在很大不便。


方式二:对RocketMQ的 client 和 server 只进行少量修改。如果 server 存在能力缺失,会开发辅助的 server 或以 proxy 进行补充。我们在 client 之上包装了一层 MQ SDK,对用户屏蔽了具体实现。快手也是基于此方式对RocketMQ进行了落地。

4.png


MQ SDK如上图,分为三层:最上层为 API ,用户与该层打交道;中间为核心层,能够实现各种通用的能力;最底层负责与具体的 MQ 交互,当前只有 RocketMQ 的实现,但未来也许会有其他消息中间件的实现。


中间层实现了热变更的能力。用户配置不写在代码里,而是在平台进行指定,指定以后热生效,SDK 会直接加载新的配置并自动 reload 用户程序,无需重启。


5.png

RocketMQ 会分配 Logic topic,业务代码无需关心集群在哪,无需关心当前环境,也无需关心数据标记比如压测、泳道,只需使用我们提供的非常简单的 API ,复杂的过程全部在核心层进行封装,对业务用户屏蔽。


6.jpeg

上图为跨机房负载均衡的实现流程。


所有Logic topic 都会映射到上图中间的两个机房,每个机房部署一个集群。RocketMQ 集群可以有多个 broker ,生产者和消费者对 broker 有故障感知和转移能力,能够通过 NameServer 发现哪个 broker 故障以避免与其进行连接。为了实现更好的控制,我们在集群之上又封装了一层负载均衡,并在 client 端实现。


每一个 Logic topic 都被分配到两个集群,生产者在生产时会同时连接到两个集群。两个集群分别位于不同 IDC,同一地区的两个IDC之间延时大约为1-2ms。消费者侧也是双连,一旦某机房或集群发生故障,流量会立刻自动转移到另一机房。


我们将生产端的自动负载均衡(自动failover)进行了抽象封装,做成了开源项目。Failover 组件与 RocketMQ 无关,在主调方做 RPC 或消息生产等调用时,会检查被调方的健康度。如果被调方不健康或响应很慢,则会调低其权重。


扫描上方二维码,了解更多关于该组件的功能。

7.png


RocketMQ 实现了简单的延迟消息,但是只能实现几个固定级别的延时,而实际的业务更希望发消息时可以任意指定延迟时间。因此我们通过外挂 Delay Server 的方式实现了任意精度的延迟消息。


Delay Server 会将用户要求延迟投递的消息进行保存,等到指定时间以后,再将消息送回原来的业务 topic 。


8.jpeg

基于PULL的模式(RocketMQ的PUSH Consumer也是基于PULL),很难直接实现动态的多泳道隔离。因此很多公司会选择根据泳道的不同将消息投递到不同的 topic,这样虽然实现了功能,但是侵入性太强,并且也不好实现多级回落。


而在快手,我们将所有泳道的消费都放在同一个 topic 里,并且实现了多级泳道回落。比如项目 A 和项目 B 同时在开发,项目 A 生产的消息由项目 A 的消费者消费。项目 A 下面有子项目A.X和A.Y,那么A.X生产的消息由A.X的消费者消费,但是如果A.Y没有消费者,因此A.Y生产的消息会回落到由 A 的消费者进行消费。


9.jpeg


快手的泳道隔离主要通过 RPC 转发实现。


如上图,黄色线代表项目 A 的数据流向,橙色线代表项目 B 的数据流向。SDK 会在将数据交给业务用户之前,先检查数据的泳道标记是否匹配,如果不匹配,则会通过 RPC 的方式转发至匹配的消费者。


这样我们等于是将 PULL 转为了 PUSH,在主调方进行选择,所以能够将所有项目放在同一个 topic 里,且能够实现隔离。


10.png


RocketMQ 是基于 queue 来进行客户端的 rebanance,如果消费者的数量大于queue,则会导致部分消费者无事可做;或有时 queue 分配不均匀,导致部分消费者负担大、部分消费者负担小。


我们通过RPC的方式实现了消费 Proxy,先从 RocketMQ 的 broker 消费数据,再通过 RPC 的方式  PUSH 到 consumer。


消费 proxy 的 RPC 与前文的 RPC 转发使用同一套机制,因此RocketMQ 不需要过多的 queue, 但可以有很多消费者。消费 proxy 为可选项,只需在平台指定消费方式,无需修改代码也无需重启,即可直接热生效。


11.jpeg

此外,我们开发了拨测程序,生成了一个模拟的生产者和消费者。生产者会往线上所有集群的每一个 broker 发送消息,包括普通消息、定时消息和事务消息。消费者消费到消息后,会取出消息体内生产者的 IP 地址,然后通过 TCP 的方式 ACK 回生产者,告知生产者消息是否丢失、是否重复以及从生产到消费的延迟是多少。


另外,还可以针对生产者和消费者进行各种配置,比如消息体大小、生产速率、对账抽样比例、对账周期等。比如在配置中将速率调大,即可实现压测,生产者和消费者会进行打点,最终可在 Grafana 上进行查看和告警。


性能篇


对 RocketMQ 进行性能优化后,300字节小消息生产 TPS 提升54%,同时 CPU占用降低11%;600 queue消费性能提升200%,跨IDC 100KB大消息单线程生产 TPS 提升693%,跨IDC 100KB集群消费吞吐提升250%。


优化主要分为两批。

12.png


第一批优化集中在RocketMQ4.9.1版本,包括清除多余的日志、消除不必要的锁、消除主从复制中的数组拷贝、优化Broker的默认参数、优化锁内操作的性能并将部分操作抽取到锁外、优化消息属性编解码的性能以及优化消息Header解析的性能。扫描二维码可阅读本次优化相关的完整文章。


另外,RocketMQ 4.9.0版本的默认参数设置不合理,因此我们在4.9.1版本对其进行了优化,使得性能有了巨大提升。


13.png

上图为第二批优化的目标:

  • 降低 CPU 开销。RocketMQ 不消耗 CPU,但是在混合部署场景下,CPU 极有可能会成为问题,因此需要对 CPU 开销进行优化。  
  • 提升跨机房的生产、消费的吞吐。
  • 提升大消息的吞吐。
  • 提升queue特别多的场景下的消费性能。


第二批优化大部分集中在社区的ISSUE3585 里,扫描上方二维码可阅读完整文章。


14.png

上图为第二批优化CPU 方面的具体内容,字母编号与 ISSUE3585 相对应。此前RocketMQ 使用 Fastjson 做序列化,而有一个自定义的协议性能略微优于 Fastjson,我们对其进行了深入研究和优化,最终使得 RocketMQ 在编解码上性能也得到了很大提升。


15.png

RocketMQ 构建 Queue 的程序为单线程,因此我们使用mmap buffer 代替 FileChannel,性能得到了极大提高。


上图红框中为某方法优化前后对比。


16.png

此外,我们将 Pull 通知移动到另外的线程,使其不占用线程的资源。同时,将通知自动聚批,兼顾高吞吐和低延迟,只有 TPS 较高时才会自动打开,阈值可设置,避免 Pull 通知在 Broker 和消费者之间震荡频率过高,消耗 CPU。


17.png


大消息性能不佳也是一直以来很大的困扰,经过分析我们发现 RocketMQ remoting 的 TCP 参数设置有待优化。原先的buffer 设置为固定值,当机房延迟很大时,过小的 buffer 会导致 TCP 连接的吞吐受到严重影响。因此,我们将 buffer 修改为由操作系统自动管理,以保证吞吐。


上图列出了线上实测的数据表,可以看出消费的性能提升了数倍。


18.png


在极高的 TPS 场景下,如果消息体较大,则操作系统内存分配可能会成为 RocketMQ 的瓶颈,4.X 的内核下的表现远远优于 3 .X 。极端场景下,3.X内核通常需要将参数 min_free_kbytes 调至较大值。


19.png


我们于2021年12月社区开发者会议现场演示了性能测试,对比了第二批优化前后的4.9.2版本和4.9.3 Snapshot版本(包括当时还未合并进该版本的B和K的优化)的性能。


测试时,在电脑上同时运行所有 broker、生产者、消费者。老版本TPS不到 3w,而新版本有了自动聚批的能力,TPS 可达 6 w,相比于老版本提升了一倍。


加入 Apache RocketMQ 社区


十年铸剑,Apache RocketMQ 的成长离不开全球接近 500 位开发者的积极参与贡献,相信在下个版本你就是 Apache RocketMQ 的贡献者,在社区不仅可以结识社区大牛,提升技术水平,也可以提升个人影响力,促进自身成长。

社区 5.0 版本正在进行着如火如荼的开发,另外还有接近 30 个 SIG(兴趣小组)等你加
入,欢迎立志打造世界级分布式系统的同学加入社区,添加社区开发者微信:rocketmq666 即可进群,参与贡献,打造下一代消息、事件、流融合处理平台。

20.jpeg

微信扫码添加小火箭进群

另外还可以加入钉钉群与 RocketMQ 爱好者一起广泛讨论:

21.png

钉钉扫码加群

关注「Apache RocketMQ」公众号,获取更多技术干货

相关实践学习
快速体验阿里云云消息队列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
相关文章
|
4月前
|
消息中间件 存储 Kafka
一文带你从入门到实战全面掌握RocketMQ核心概念、架构部署、实践应用和高级特性
本文详细介绍了分布式消息中间件RocketMQ的核心概念、部署方式及使用方法。RocketMQ由阿里研发并开源,具有高性能、高可靠性和分布式特性,广泛应用于金融、互联网等领域。文章从环境搭建到消息类型的实战(普通消息、延迟消息、顺序消息和事务消息)进行了全面解析,并对比了三种消费者类型(PushConsumer、SimpleConsumer和PullConsumer)的特点与适用场景。最后总结了使用RocketMQ时的关键注意事项,如Topic和Tag的设计、监控告警的重要性以及性能与可靠性的平衡。通过学习本文,读者可掌握RocketMQ的使用精髓并灵活应用于实际项目中。
2357 9
 一文带你从入门到实战全面掌握RocketMQ核心概念、架构部署、实践应用和高级特性
|
9月前
|
消息中间件 存储 监控
活动实践 | 快速体验云消息队列RocketMQ版
本方案介绍如何使用阿里云消息队列RocketMQ版Serverless实例进行消息管理。主要步骤包括获取接入点、创建Topic和订阅组、收发消息、查看消息轨迹及仪表盘监控。通过这些操作,用户可以轻松实现消息的全生命周期管理,确保消息收发的高效与可靠。此外,还提供了消费验证、下载消息等功能,方便用户进行详细的消息处理与调试。
|
6月前
|
消息中间件 存储 设计模式
RocketMQ原理—5.高可用+高并发+高性能架构
本文主要从高可用架构、高并发架构、高性能架构三个方面来介绍RocketMQ的原理。
1555 21
RocketMQ原理—5.高可用+高并发+高性能架构
|
12月前
|
消息中间件 存储 Serverless
【实践】快速学会使用阿里云消息队列RabbitMQ版
云消息队列 RabbitMQ 版是一款基于高可用分布式存储架构实现的 AMQP 0-9-1协议的消息产品。云消息队列 RabbitMQ 版兼容开源 RabbitMQ 客户端,解决开源各种稳定性痛点(例如消息堆积、脑裂等问题),同时具备高并发、分布式、灵活扩缩容等云消息服务优势。
288 2
|
消息中间件 Java Apache
RocketMQ消息回溯实践与解析
在分布式系统和高并发应用的开发中,消息队列扮演着至关重要的角色,而RocketMQ作为阿里巴巴开源的一款高性能消息中间件,以其高吞吐量、高可用性和灵活的配置能力,在业界得到了广泛应用。本文将围绕RocketMQ的消息回溯功能进行实践与解析,分享工作学习中的技术干货。
238 4
|
消息中间件 弹性计算 Kubernetes
RabbitMQ与容器化技术的集成实践
【8月更文第28天】RabbitMQ 是一个开源消息代理和队列服务器,用于在分布式系统中存储、转发消息。随着微服务架构的普及,容器化技术(如 Docker 和 Kubernetes)成为了部署和管理应用程序的标准方式。本文将探讨如何使用 Docker 和 Kubernetes 在生产环境中部署和管理 RabbitMQ 服务,同时保证高可用性和弹性伸缩能力。
281 3
|
12月前
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
284 111
|
7月前
|
消息中间件 人工智能 自然语言处理
基于 RocketMQ 事件驱动架构的 AI 应用实践
基于 RocketMQ 事件驱动架构的 AI 应用实践
197 2
|
10月前
|
消息中间件 Java 开发工具
【实践】快速学会使用云消息队列RabbitMQ版
本次分享的主题是快速学会使用云消息队列RabbitMQ版的实践。内容包括:如何创建和配置RabbitMQ实例,如Vhost、Exchange、Queue等;如何通过阿里云控制台管理静态用户名密码和AccessKey;以及如何使用RabbitMQ开源客户端进行消息生产和消费测试。最后介绍了实验资源的回收步骤,确保资源合理利用。通过详细的操作指南,帮助用户快速上手并掌握RabbitMQ的使用方法。
780 10
|
12月前
|
消息中间件
解决方案 | 云消息队列RabbitMQ实践获奖名单公布!
云消息队列RabbitMQ实践获奖名单公布!
170 1

相关产品

  • 云消息队列 MQ