Skip to content

02: RobustMQ: 技术设计理念综述

RobustMQ 是基于 Rust 构建的新一代高性能多协议消息队列。愿景是成为新一代云原生与 AI 原生消息基础设施。它不是简单的"又一个消息队列",而是面向AI时代和云原生需求,对消息队列进行的一次重新思考和设计。

《RobustMQ:用 Rust 重新定义云原生消息队列的未来》中我们定义了RobustMQ 有六个特点:高性能、Serverless、插件式存储、极简高内聚架构、 计算/存储/调度分离、多协议。

整体来看,这六个特点就是 RobustMQ 希望成为新一代高性能多协议消息队列的核心技术理念。接下来我们将展开说明我们针对这六个特点的思考过程。

从架构设计理念上,RobustMQ 吸收参考了当前业界主流消息队列、主流基础设施软件(比如数据库、分布式存储)的优势和缺陷。结合对消息中间件业务使用的理解,希望打造一个能满足各种场景的开源消息队列产品。因此本文只代表现阶段的架构设计总结。长期来看,架构会不断的演进和更新。

高性能

在 RobustMQ 设计之初,第一个关键词是高性能。目前主流消息队列都是用Java 构建,Java 相比其他语言在GC停顿、语言性能层面确实相比C/C++会有降低。因此业界也有很多消息队列试图基于C++来实现,做的比较好的产品是RedPanda。

RobustMQ 的开发者曾经也使用过C++构建消息队列,但是因为C++的开发效率,内存泄漏等安全风险,导致项目成熟周期太长,导致最终不是特别理想。 而 rust 的出现,让我们看到了曙光。从业界实践来看,我们认为从性能、开发效率、安全风险等角度来看,可以解决我们之前用C++开发时遇到的问题,且性能上会有显著提升。

因此,RobustMQ 希望基于 Rust 的语言优势,通过良好的架构设计、编码实现来达到高性能的目的。从落地来看,基于 Rust 构建的消息流引擎Iggy,它号称耗时可以到纳秒级别。这也证明了该语言的选择优势。

Serverless

第二个关键字是 Serverless。随着云技术、K8s/Docker、云盘、分布式存储(比如云对象存储,MinIo)的普及。传统消息队列如Kafka、RocketMQ、RabbitMQ 存算一体 + 本地存储的系统架构导致其无法真正利用到云和K8s技术优势。无法做到真正的按需使用,弹性扩缩容。因此 Pulsar 基于Apache Bookkeeper 构建了存算分离的架构。希望通过存算分离的架构来解决传统消息队列无法弹性扩缩容的问题。这个设计理念在当时(19年左右)消息队列这个领域,是一个非常棒的创新和参考,是一个对的方向,值得参考和借鉴。

因此,RobustMQ 首先就是实现存算分离架构。

插件化存储

第三个关键字是插件化存储。类比Pulsar 使用Bookkeeper 作为存储引擎,现在业界的消息队列的一个技术趋势是使用分布式存储(比如云对象存储、数据湖,HDFS)来作为消息队列底层的存储引擎。从而达到存算分离 + 存储降本的作用。这种技术路线的优势是即利用了当前公有云架构的优势,大大降低了自身开发存储层的工作量和数据存储成本。但是它带来的问题是:

  1. 读写性能的下降(虽然业界有一些提升性能的思路,比如本地高性能盘预热数据、WAL等等),但是毋庸置疑的是,这个技术路线带来的第一个问题是性能无法达到极致。因此这个技术路线它是满足的是数据量大,对成本要求高、延时不敏感的业务场景。但是在很多场景中(比如金融场景),业务对消息队列的延时需求是稳定的10毫秒级,甚至更低。

  2. 不是所有业务都允许使用云服务,在很多场景中,数据都有本地存储的需求。如果必须依赖云存储,那么在这种场景下该技术路线是无法满足的。

而 RobustMQ 希望能够打造一个满足各个场景的消息队列,既能解决成本、也能解决性能、多部署场景的需求。

因此,RobustMQ 将存储层设计为可插拔的。并内置了内存、本地分段多副本存储、远程分布式存储(对象存储、HDFS等)。业务可以根据需求在集群、Topic 维度选择存储引擎。去满足各种场景。

高内聚架构

第四个关键词是高内聚架构。目前主流消息队列的一个很大的性能瓶颈和稳定性风险是元数据存储(如Topic、节点等元数据)。比如Kafka和Pulsar 最开始都是基于Zookeeper来完成元数据存储和分布式协调的工作。今天Kafka 花费了大量精力剥离Zookeeper,基于Raft 协议构建了内置的元数据存储。Pulsar 也花费了很大精力支持了多种元数据存储服务。从技术思路上来看,当一个分布式服务依赖另一个分布式服务,无论从功能适配度,稳定性,性能来看,都会存在很大的风险和瓶颈。这也是Kafka和Pulsar 在自建和剥离第三方元数据组件的原因。

因此,RobustMQ 在设计之初就希望自身是一个高内聚架构,即一个二进制文件即可拉起集群,无任何外部依赖。这有益于长期架构的演进、稳定性、且可以降低运维成本。

计算、存储、调度分离

第五个关键词是计算、存储、调度分离。在分布式集群中,会有很多集群内部的协调工作。如果依赖元数据存储服务,当前主流消息队列都会选择在计算集群中选择一台节点来完成这个工作。在robustMQ 中,我们将协调功能挪到了元数据存储服务中,也就是说Broker 做到了完全计算,只需要负责消息数据的读写。从而达到计算、存储、调度三层分离的能力。这样做的好处是,任何一层都可以快速、独立的弹性扩缩容而不会相互影响。比如集群部署在K8s中,无论哪一层出现瓶颈,都可以快速扩缩容,而不会因为架构耦合带来的扩缩容问题。

多协议

第六个关键词是多协议。在消息队列业界,有两条明显的方向,一条是关注性能、功能、可靠性的消息方向,代表产品是RocketMQ、RabbitMQ。另一条是关注吞吐的流方向,代表作品是Kafka。这导致业务在不同的场景下需要选择不同的产品。关键的是不同产品的协议及其客户端 SDK 是不一样的。也就是说业务选择不同的产品时需要修改业务代码,从而大大加大了业务切换的成本。而近几年业界提出的流批一提、消息和流融合等概念的驱动下。也即使说如果能有一款消息队列产品能够兼容多种协议,满足不同场景,那么在企业效率、成本、稳定性方面都会是大大的助力。

因此,RobustMQ 不会新设计通信协议,会兼容主流的消息队列协议,比如MQTT、Kafka、AMQP、RocketMQ,甚至Pulsar。这种方式的好处是,RobustMQ 可以专注内核,不需要花经历构建生态。并且让业务无需任何改动,业务 0 成本迁移。另一方面,当RobustMQ 足够成熟时,可以大大加快RobustMQ 的推广使用速度。

总结

总结来看,RobustMQ 的核心技术思想是:

  1. 基于 Rust 实现高性能的消息队列内核。
  2. 基于计算、存储、调度分离的三层架构,每一层都具备完全弹性扩缩容能力,从而让系统具备完整的Serverless 能力。
  3. 基于插件化存储的能力,满足不同场景下对存储引擎的需求,比如成本或性能。
  4. 基于多协议适配,兼容当前生态,专注内核,降低业务的切换成本。
  5. 高内聚内核,无外部依赖,一个二进制,一键拉起集群。