本文作者:黄理,快手在线音讯零碎负责人。
快手对于 RocketMQ 社区版本的优化个别为在其外层进行能力的构建,而不是对其外部进行大改变,因为外部大改不利于前期的版本升级。即便对外部 RocketMQ 进行了批改,咱们也会尽量通过 PR 将新个性回馈到社区。
快手会定期对 RocketMQ 进行降级。2022 年春节,咱们大胆应用了尚未正式公布的 RocketMQ 4.9.3-SNAPSHOT 版本,安稳度过了快手一年中最重要的流动,这也证实了社区版本 RocketMQ 的兼容性和稳定性。
利用篇
RocketMQ 进入快手两年内,从 0 倒退到每天数千亿音讯级别。快手是 RocketMQ 社区版本的事务音讯最早的大规模用户,目前每天有百亿以上的事务音讯和定时音讯,实现了跨 IDC 的主动负载平衡以及容灾,实现了多级泳道(我的项目)互不烦扰,多个我的项目可同时开发,以及可回落。
RocketMQ 的落地形式个别为两种。
形式一 :在开源软件的根底上进行批改,可能疾速轻松地实现须要的性能,但后续降级存在很大不便。
形式二 :对 RocketMQ 的 client 和 server 只进行大量批改。如果 server 存在能力缺失,会开发辅助的 server 或以 proxy 进行补充。咱们在 client 之上包装了一层 MQ SDK,对用户屏蔽了具体实现。快手也是基于此形式对 RocketMQ 进行了落地。
MQ SDK 如上图,分为三层:最上层为 API,用户与该层打交道;两头为核心层,可能实现各种通用的能力;最底层负责与具体的 MQ 交互,以后只有 RocketMQ 的实现,但将来兴许会有其余消息中间件的实现。
中间层实现了热变更的能力。用户配置不写在代码里,而是在平台进行指定,指定当前热失效,SDK 会间接加载新的配置并主动 reload 用户程序,无需重启。
RocketMQ 会调配 Logic topic,业务代码无需关怀集群在哪,无需关怀以后环境,也无需关怀数据标记比方压测、泳道,只需应用咱们提供的非常简单的 API,简单的过程全副在核心层进行封装,对业务用户屏蔽。
上图为跨机房负载平衡的实现流程。
所有 Logic topic 都会映射到上图两头的两个机房,每个机房部署一个集群。RocketMQ 集群能够有多个 broker,生产者和消费者对 broker 有故障感知和转移能力,可能通过 NameServer 发现哪个 broker 故障以防止与其进行连贯。为了实现更好的管制,咱们在集群之上又封装了一层负载平衡,并在 client 端实现。
每一个 Logic topic 都被调配到两个集群,生产者在生产时会同时连贯到两个集群。两个集群别离位于不同 IDC,同一地区的两个 IDC 之间延时大概为 1 -2ms。消费者侧也是双连,一旦某机房或集群产生故障,流量会立即主动转移到另一机房。
咱们将生产端的主动负载平衡(主动 failover)进行了形象封装,做成了开源我的项目。Failover 组件与 RocketMQ 无关,在主调方做 RPC 或音讯生产等调用时,会查看被调方的衰弱度。如果被调方不衰弱或响应很慢,则会调低其权重。
扫描上方二维码,理解更多对于该组件的性能。
RocketMQ 实现了简略的提早音讯,然而只能实现几个固定级别的延时,而理论的业务更心愿发消息时能够任意指定延迟时间。因而咱们通过外挂 Delay Server 的形式实现了任意精度的提早音讯。
Delay Server 会将用户要求提早投递的音讯进行保留,等到指定工夫当前,再将音讯送回原来的业务 topic。
基于 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 的消费者进行生产。
快手的泳道隔离次要通过 RPC 转发实现。
如上图,黄色线代表我的项目 A 的数据流向,橙色线代表我的项目 B 的数据流向。SDK 会在将数据交给业务用户之前,先检查数据的泳道标记是否匹配,如果不匹配,则会通过 RPC 的形式转发至匹配的消费者。
这样咱们等于是将 PULL 转为了 PUSH,在主调方进行抉择,所以可能将所有我的项目放在同一个 topic 里,且可能实现隔离。
RocketMQ 是基于 queue 来进行客户端的 rebanance,如果消费者的数量大于 queue,则会导致局部消费者无事可做;或有时 queue 调配不平均,导致局部消费者累赘大、局部消费者累赘小。
咱们通过 RPC 的形式实现了生产 Proxy,先从 RocketMQ 的 broker 生产数据,再通过 RPC 的形式 PUSH 到 consumer。
生产 proxy 的 RPC 与前文的 RPC 转发应用同一套机制,因而 RocketMQ 不须要过多的 queue,但能够有很多消费者。生产 proxy 为可选项,只需在平台指定生产形式,无需批改代码也无需重启,即可间接热失效。
此外,咱们开发了拨测程序,生成了一个模仿的生产者和消费者。生产者会往线上所有集群的每一个 broker 发送音讯,包含一般音讯、定时音讯和事务音讯。消费者生产到音讯后,会取出音讯体内生产者的 IP 地址,而后通过 TCP 的形式 ACK 回生产者,告知生产者音讯是否失落、是否反复以及从生产到生产的提早是多少。
另外,还能够针对生产者和消费者进行各种配置,比方音讯体大小、生产速率、对账抽样比例、对账周期等。比方在配置中将速率调大,即可实现压测,生产者和消费者会进行打点,最终可在 Grafana 上进行查看和告警。
性能篇
对 RocketMQ 进行性能优化后,300 字节小音讯生产 TPS 晋升 54%,同时 CPU 占用升高 11%;600 queue 生产性能晋升 200%,跨 IDC 100KB 大音讯单线程生产 TPS 晋升 693%,跨 IDC 100KB 集群生产吞吐晋升 250%。
优化次要分为两批。
第一批优化集中在 RocketMQ4.9.1 版本,包含革除多余的日志、打消不必要的锁、打消主从复制中的数组拷贝、优化 Broker 的默认参数、优化锁内操作的性能并将局部操作抽取到锁外、优化音讯属性编解码的性能以及优化音讯 Header 解析的性能。扫描二维码可浏览本次优化相干的残缺文章。
另外,RocketMQ 4.9.0 版本的默认参数设置不合理,因而咱们在 4.9.1 版本对其进行了优化,使得性能有了微小晋升。
上图为第二批优化的指标:
- 升高 CPU 开销。RocketMQ 不耗费 CPU,然而在混合部署场景下,CPU 极有可能会成为问题,因而须要对 CPU 开销进行优化。
- 晋升跨机房的生产、生产的吞吐。
- 晋升大音讯的吞吐。
- 晋升 queue 特地多的场景下的生产性能。
第二批优化大部分集中在社区的 ISSUE3585 里,扫描上方二维码可浏览残缺文章。
上图为第二批优化 CPU 方面的具体内容,字母编号与 ISSUE3585 绝对应。此前 RocketMQ 应用 Fastjson 做序列化,而有一个自定义的协定性能稍微优于 Fastjson,咱们对其进行了深入研究和优化,最终使得 RocketMQ 在编解码上性能也失去了很大晋升。
RocketMQ 构建 Queue 的程序为单线程,因而咱们应用 mmap buffer 代替 FileChannel,性能失去了极大进步。
上图红框中为某办法优化前后比照。
此外,咱们将 Pull 告诉挪动到另外的线程,使其不占用线程的资源。同时,将告诉主动聚批,兼顾高吞吐和低提早,只有 TPS 较高时才会主动关上,阈值可设置,防止 Pull 告诉在 Broker 和消费者之间震荡频率过高,耗费 CPU。
大音讯性能不佳也是始终以来很大的困扰,通过剖析咱们发现 RocketMQ remoting 的 TCP 参数设置有待优化。原先的 buffer 设置为固定值,当机房提早很大时,过小的 buffer 会导致 TCP 连贯的吞吐受到重大影响。因而,咱们将 buffer 批改为由操作系统主动治理,以保障吞吐。
上图列出了线上实测的数据表,能够看出生产的性能晋升了数倍。
在极高的 TPS 场景下,如果音讯体较大,则操作系统内存调配可能会成为 RocketMQ 的瓶颈,4.X 的内核下的体现远远优于 3 .X。极其场景下,3.X 内核通常须要将参数 min_free_kbytes 调至较大值。
咱们于 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 即可进群,参加奉献,打造下一代音讯、事件、流交融解决平台。
微信扫码增加小火箭进群
另外还能够退出钉钉群与 RocketMQ 爱好者一起宽泛探讨:
钉钉扫码加群
关注「Apache RocketMQ」公众号,获取更多技术干货