十问 RocketMQ:十年再出发,到底有何不同?
背景
作为一种实时数据的处理平台,消息系统的发展跟业务架构的变迁一直息息相关,那么我们可以透过业务架构的变化来看消息系统的发展历程和未来趋势。经过十多年的发展,RocketMQ 逐渐成为了一个消息、事件和流一体的超融合处理平台。
在消息领域,全面拥抱云原生技术,弹性伸缩,开箱即用。在事件领域,产品形态全面升级,拥抱行业标准,让事件驱动架构无处不在,从单一业务的数字化系统,扩展到跨业务、跨组织的数字化商业生态。事件驱动架构同时也让云计算、云原生的技术能够更大规模的落地,提高云产品和用户业务的集成度,让 Serverless 技术被更大范围的采纳,为客户降本增效。在流领域,流存储增强批量特性,大幅度提高数据吞吐量;新增逻辑队列能力,解耦逻辑资源和物理资源,在流场景也具备无缝伸缩能力;新增轻量流处理引擎,提供实时事件流处理、流分析能力。
云原生时代,RocketMQ 全新升级背后的原因是什么?我们选取了十大问题,抛给阿里云 RocketMQ 团队,听听他们对于产品发展与决策的思考。
十问 RocketMQ
消息中间件有着近 30 年的行业历史,其在业务开发过程中扮演的角色发生过哪些变化?
消息队列属于最经典的中间件之一,已经有 30 多年的历史,其发展历程可以总结为几个阶段:
-
第一阶段,2000 年之前。这个阶段的消息队列供应商是几家商业软件巨头,比如 IBM、Oracle、Microsoft 都有自己的商业化 MQ,其中最具代表性的是 IBM MQ,价格昂贵,面向高端企业,主要是大型金融、电信等企业;这类商业 MQ 一般采用高端硬件,软硬件一体机交付,MQ 本身的软件架构是单机架构。
-
第二阶段,2000~2007 年。进入 00 年代后,初代开源消息队列崛起,诞生了 JMS、AMQP 两大标准,与之对应的两个实现分别为 ActiveMQ、RabbitMQ,他们引领了初期的开源消息队列技术。开源极大的促进了消息队列的流行、降低了使用门槛,技术普惠化,逐渐成为了企业级架构的标配。
-
第三阶段,2007~2017 年。PC 互联网、移动互联网爆发式发展。由于传统的消息队列无法承受亿级用户的访问流量和海量数据传输,诞生了互联网消息中间件,核心能力是全面采用分布式架构、具备很强的横向扩展能力,开源典型代表有 Kafka、RocketMQ,闭源的还有淘宝 Notify。
在前两个阶段,消息中间件在业务开发过程中,单纯地扮演着「异步解耦」的角色,属于软件架构的一种范式,业务通过引入消息中间件来解决同步架构带来的耦合问题。进入到第三个阶段后,互联网的海浪数据是前两个阶段无法想象的,对于业务来讲单纯的异步解耦远远不够的,在互联网的流量下,消息队列的消费者会轻易被打垮,这个时候业务对消息中间件的需求多了「堆积和削峰」,RocketMQ 便是在这个背景下诞生的,通过 RocketMQ 对流量进行削峰,让业务有机会通过平稳的流量处理海量的堆积数据,这项技术是支撑淘宝天猫每年双十一的利器。
进入互联网时代以来,消息队列跟互联网业务相辅相成,经历了快速发展的阶段,消息队列在业务开发过程中也逐渐从「架构层面」深入到「业务层面」。在这期间,RocketMQ 做了大量业务上的创新来满足业务的快速迭代需求,这其中最典型的就是 RocketMQ 在支撑阿里集团和阿里云用户过程中孵化出来的 「全类型业务消息」,这些消息可以说承担了相当于一部分的业务逻辑。
全类型的业务消息固然大大提高了互联网业务的迭代速度,但互联网的规模对消息队列的挑战远不止于此,互联网业务对消息队列的消息处理和服务能力都有极高的要求,RocketMQ 为服务互联网业务诞生了大量领先的消息处理能力,比如阿里的交易消息(Notify),订阅比达到了 1:300,但是投递比只有 15:300,SQL 过滤的能力就是用来解决这种高订阅比、低投递比的业务场景的。除此之外,RocketMQ 提供了大量的消息治理能力,包括消息回放、消息重试、死信消息等。
RocketMQ 将消息的治理能力在容灾方面发挥到了极致,大家都知道互联网业务对可用性有着极高的追求,阿里内部的数据库和中间件在各个商业化版本里面都提供了容灾能力,来满足互联网用户对于容灾高可用需求。
RocketMQ 创新性地通过组合流量管控和数据复制「全球消息路由」方面的技术沉淀提供了多活和灾备的解决方案。
总结下来,消息队列在发展的过程当中,从最初的帮助业务进行「异步解耦」,到互联网时代的堆积和削峰,再到后来从架构层面深入到业务层面,通过不同的业务消息来沉淀通用的开发范式,到最后通过领先的消息治理和服务能力,来满足互联网业务对业务管控和多活容灾等方面的需求。可以说 RocketMQ 发展至今已经深入到了业务的架构、开发范式、运维管控、可观测性、容灾架构等方方面面。
在消息中间件的发展历史当中,业务开发架构有过哪些升级,消息系统又是如何去适配这些变化的?
消息的发展跟业务架构的变迁是息息相关的,业务最开始采用的架构是「单体架构」,其开发、运维和迭代都非常简单,但受限于其扩展能力,业务很快便向「分布式架构」演进,早在 2008 年淘宝和天猫发起一次最大规模的架构升级,启动了“五彩石”项目,把单体应用拆分成分布式应用,同时抽象淘宝、天猫的共同底座-业务中台,包括交易中心、商品中心、买家中心等。在业务中台之下,同时诞生了阿里中间件(初期三大件包括消息、RPC、分布式数据层),RocketMQ 是其中之一。
可以说,RocketMQ 诞生于「分布式架构」阶段,在这个阶段,业务对「分布式」并没有达成共识,各个公司对单体应用的拆分方式也是五花八门的,有垂直拆分,有水平分层,有按组件拆分,也有按服务拆分,但最终微服务架构逐渐成为了业界主流。但不管业务如何去落地分布式架构,消息系统在里面总是以「分布式通信」的原子能力去适配这些变化的,无论分布式应用是如何组织业务架构的,消息系统在这个阶段总是作为「分布式应用的通信基础设施」来助力业务架构的快速变迁,最终演进到较为理想的微服务架构。
近些年,应用的拆分粒度从「微服务」有逐渐向「单个函数」演进的趋势,应用呈现出所谓的 Serverless 架构,通过函数构建的应用粒度更细,每个函数往往是单个操作,函数的编排和驱动面临着非常大的挑战。消息系统作为通道除了发挥「通信设施」作用,在函数计算场景,会进一步承担「集成与被集成」的角色,帮助函数计算编排函数,集成各类事件源,成为函数计算的驱动力。
从业界技术流行趋势来看,微服务当下仍是主流,且 Service Mesh、Dapr、Knative 等新兴的技术框架让微服务的形态呈现了多样化,RocketMQ 在更好地支持微服务架构方向上有哪些演进?
微服务架构发展至今,特别是服务网格的思想兴起后,微服务形态呈现出多样化,不管是 Dapr 还是 Knative,这些新兴的技术框架主要遵循两个关键思想:
-
将分布式的基础能力进行下沉,比如植入到 Sidecar 当中,这些分布式的基础能力包括服务发现、负载均衡、远程调用、发布订阅(消息中间件)。
-
对分布式能力进行抽象,新的微服务架构定义了抽象的 API,用于屏蔽分布式能力的具体实现,比如 Dapr 在其 DaprClient 中就对消息的 Pub/Sub 进行了全新的 API 定义;Knative 也基于 Kubernetes 的可扩展 API 定义了 Subscription 概念。
简而言之,新兴的微服务技术框架会将分布式应用需要的基础能力进行抽象和封装,并进一步植入到 Sidecar 或者自定义的 Runtime 当中。消息中间件作为分布式应用基础的通信能力,为了适配这些技术框架,需要加强自身的「被集成」能力,RocketMQ 5.0 在这方面有两块技术演进。
首先是轻量级 SDK,RocketMQ 5.0 推出了基于 gRPC 全新的多语言 SDK,这套 SDK 有几个重要特点:
-
采用全新极简的 API,拥有不可变 API 的设计,完善的错误处理,各语言 SDK API 在本地语言层面对齐,新的 API 化繁为简,更易被使用和集成。
-
采用云原生的 RPC 标准框架 gRPC,标准的传输层框架,更易被拦截,特别适合被 Service Mesh 集成从而赋予其更多的传输层基础能力。
-
客户端轻量化,以典型的「SimpleConsumer」为代表,采用全新的面向消息的无状态消费模型,整个 SDK 从代码到运行时都极为轻量。轻量化是一种非常重要能力,如果各个中间件都采取富客户端的形式,这些中间件当被一起植入到 Sidecar 中时,也会是一个非常庞大的 Sidecar,应用框架集成的复杂度非常高。
另一块就是无状态的消费模型,RocketMQ 5.0 引入了 Pop 机制,创新性地在队列模型之上支持了无状态的消息模型,在一个主体上同时支持两种消费模型,体现了消息和流的「二象性」,面向流场景采用高性能的队列模型进行消费,面向消息的场景,采用无状态的消息模型进行消费,业务可以只关心消息本身,通过「SimpleConsumer」提供单条消息级别的消费、重试、修改不可见时间、以及删除等 API 能力。
总结下来,RocketMQ 5.0 在面临多样化的微服务生态时,通过强化自身被集成的能力,来更好的支持微服务技术架构的创新和演进。
近两年,包括中间件、数据库等各类云产品都宣称完成了云原生升级,站在云厂商的视角,业务应用应该如何进行云原生升级?
业界对于云原生的定义也是众说纷纭,对于软件来讲,我们认为「生于云,长于云」,通过云的基础设施来构建自身的软件可以称之为云原生软件。从这个角度来看,RocketMQ 作为业界第一个提供公有云服务的开源消息队列可以说是最云原生的消息队列。RocketMQ 5.0 全面走向多样化、标准化一级云原生化,同时在 IoT、边缘计算、事件驱动等新趋势都有相应的布局和落地实现。
RocketMQ 自上云以来,一直依赖阿里云的基础设施强化产品的竞争力,充分地利用云的弹性能力,撬动云的计算、存储和网络的池化资源,以支撑业务完成云原生的改造。RocketMQ 5.0 商业版在计算、存储、和网络三个方面都有重大的云原生改造升级:
-
在计算层面,RocketMQ 5.0 通过 ACK 充分利用 ECS 弹性能力,采取弹性资源池 + HPA 相关技术支持计算能力快速弹性,同时 ACK 自带的跨可用区部署能力为云产品提供了充足的高可用保障。
-
在网络层面,RocketMQ 接入了阿里云的多种网络能力,满足用户对多样性网络的需求,公网随开随用,支持多种私网网络形态,基于 CEN 构建了全球互通的消息网络。
-
在存储方面,通过推出多级存储产品化的能力,充分利用 OSS 存储的弹性能力,存储计费走向按量付费,同时支持冷热数据分离,为用户提供一致的冷读 SLA。
从 RocketMQ 自身的经历来看,云产品的云原生化的目标是充分利用云的基础设施能力,利用云的弹性能力,实现云原生技术的普惠,可以说基于云产品构建的应用就是云原生化的应用,通过对应用进行云原生化的改造,任何一个企业用户背后都有着阿里云超大规模资源池的支撑,能满足业务爆发式增长的需求。
完成云原生升级的应用构成成分更加复杂,以前多个微服务 + 数据库可能就组合成了一个应用,计算在微服务,存储在数据库。但云原生化后,计算的形态有很多种,比如可能隐藏在一个 API 网关后面,或者是一个函数计算的形态,又或者是一个容器服务的 Job。数据也散落存储在各个地方,中间件、数据库、大数据、对象存储等各个领域都提供了数据的存储与访问能力。显而易见的是,云原生化的应用虽然能够充分撬动云的能力,但对研发团队来讲,整个应用生命周期的各个环节的都需要有新的工具和流程来进行规范化生产。
云原生的应用架构看起来更加碎片化,是否违背了开发框架应当尽最大可能让用户专注业务逻辑的初衷?
恰恰相反! 云原生的应用架构,更容易让开发者专注自身的业务逻辑。我们将构建一个分布式应用的复杂度分为「本质复杂度」和「次要复杂度」,在没有云原生之前,次要复杂度占了一个分布式应用的很大比例,开发者需要关心:
- 应用本身需要多少 Server 进行部署,弹性和成本怎么取舍?Server 宕机后怎么处理?
- 各个组件运行时状态怎么收集和查询?可观测性指标如何搭建?
- 依赖的软件,比如中间件和数据库,如何进行部署,稳定性如何保障?容量评估怎么做?
- 存储的数据如何设计生命周期?如何进行归档?
- ...
云原生的应用,通过引入消息队列、函数计算、云原生数据库、对象存储等云原生的服务,可以很大程度上卸载这些次要复杂度,开发者真正有机会做到很纯粹地专注自身的业务逻辑。
但云原生的应用因为依赖了大量云产品,不可避免构成的成分复杂了很多,所以消息队列在其中起到的「通道」和「粘合」的作用就至关重要了。
如上图所示,一个云原生的应用不可避免地需要使用消息队列来作为分布式组件之间的异步通信中间件,比如连接不同的微服务。同时,因为引入了大量云上的存储和计算资源,这些资源要发挥计算的力量需要被驱动起来,阿里云给的解决方案是通过事件驱动引擎「EventBridge」作为云原生计算的驱动力,同时作为连接型产品通过连接各个云产品,方便用户更好地用云。
云原生确实给事件驱动架构带来了更多的契机,事件驱动是一个起源很早的概念。其实 RocketMQ 的 PushConsumer 提供的 API 其实就是一种事件驱动的编程范式,但在微服务应用架构当中,集成与通信才是刚需,事件驱动的价值并没有那么明显。
在云原生时代,计算力的构成越来越多样化,通过事件驱动架构来开发云原生应用是一件非常顺理成章的事情。阿里云大概在两年前就上线了全新的事件驱动型产品:事件总线 EventBridge。目前该产品作为 RocketMQ 5.0 的重要组成部分已经完成了开源。
阿里云打造全新的云产品 EventBridge 主要是为了兑现三大业务价值:
-
统一事件枢纽。阿里云的云产品,从 IaaS 到 PaaS,每天都有数以亿计的事件产生,但却没有一种简单和统一的方式来触达这些事件;这线事件也非常独立,无法形成规模效应,很难挖掘出有用的业务价值,只有充分发挥数据的规模效应,建立起数据的血缘关系,我们才能更好的发掘出数据的价值;所以 EventBridge 要解决的第一个问题便是统一阿里云上的事件标准,作为中心化的枢纽为云用户提供一站式的事件中心。
-
事件驱动引擎。当 EventBridge 具备了海量的事件源后,配合基于 RocketMQ 开发的事件驱动引擎,通过毫秒级的触发能力,加速企业进行 EDA/Serverless 的架构升级。
-
开放与集成。以事件的形式来 「Connect Everything」是一种更加松耦合的架构,EventBridge 提供丰富的跨产品、跨平台连接能力,能够促进云产品、应用程序、SaaS 服务三者相互集成。
阿里云将 EventBridge 开源至 RocketMQ 社区,也是期望开源社区能有类似的基础设施,能够集成和整合开源生态,同时能与各个云厂商的「Hub」类产品进行集成,来达到开源和云互通的效果,让用户能够随意上云,也能随意下云。
跟行业对比,从可用性和可靠性上来看,RocketMQ 多副本机制有哪些特别之处?
跟行业对比,从可用性和可靠性上来看,RocketMQ 也有多副本机制,并经历了多个版本的演进,随着 RocketMQ 面向的场景的变化而变化,也即是说 RocketMQ 的多副本技术是服务于业务的变化的,并不是一成不变的,这其实也体现了 RocketMQ 架构上的灵活性。这也是跟行业相比最大的不同,行业的大部分多副本解决方案跟架构耦合比较深,基本上是一成不变的。
-
RocketMQ 最开始采取的 Master-Slave 架构,该架构服务于阿里内部淘系业务多年,当时业务上架构的诉求其实就是数据冷备,那个阶段包括数据库都是 Master-Slave 的架构。
-
到上云的阶段,云的时代单点故障频发,云产品需要完全面向失败而设计,故 RocketMQ 开发了基于 ZK 的 HA 架构,该架构从未开源,属于商业上的版本,依托于 Zookeeper 的分布式锁和通知机制,引入 Controller 组件负责 Broker 状态的监控以及主备状态机转换,在主不可用时,备自动切换为主。
-
再到后来,业务除了关注可用性,也越来越多地关注“故障恢复时间”,也就是 RTO 指标,基于 ZK 或者开源基于 Raft 的多副本版本 RTO 时间都较长,为了解决这个问题,商业上针对业务消息,设计了“秒级 RTO”多副本架构,包含无切换设计、节点对等、灵活 ACK、特殊消息故障转移等设计能够将集群故障恢复时间降低到秒级。
-
到 RocketMQ 5.0,需要同时面向消息和流的场景,对多副本技术有了非常高的要求,一方面在业务消息期望集群有超短的故障转移时间,另一方面流要求分区永不下线,基于这个背景,在 5.0 这个大版本当中,将商业上的秒级 RTO 架构与开源的 Dledger Controller 进行了融合,统一了消息和流的多副本方案。
为什么有各种各样的 MQ?
前面也讲过消息队列的历史,近几年可谓说是蓬勃发展了,确实出现了很多消息队列解决方案,但其实去分析每种消息队列,会发现他们诞生的背景和要针对性解决的问题是不一样的。
-
RabbitMQ 诞生于标准化与开源,打破了商业化消息队列的技术壁垒,但应用场景其实没变,定位为异步与解耦;
-
Kafka 诞生的背景是大数据,以批量,高吞吐等核心能力抢占了大数据管道的心智,随后非常自然地定位到 Streaming 领域;
-
EMQ 重点聚焦的领域在物联网,物联网的挑战跟其他领域是大相径庭的,超大规模的设备与连接数,规则引擎,甚者边缘段需要有一整套完整的解决方案;
-
Pulsar 作为后起之秀尝试在多个领域发力,包括 Messaging、Function、Streaming 等多领域都有相应布局。
回到 RocketMQ,大家能从近两年 RocketMQ 在社区的一系列动作中发现,RocketMQ 同时在消息、事件、流三个领域都有发力,逐渐演进至一个超融合处理平台。 作为一个融合的数据处理平台,RocketMQ 当前在开源的布局看起来是与业界多个 MQ 趋同,我们并非是为了做成多个 MQ 的超集,在 RocketMQ 开源的背后其实是商业上真实的需求驱动,很多场景和技术已经在内部已经孵化多年。
-
在消息领域,RocketMQ 4.0 商业上做了很多业务消息领域的创新与探索,并持续反哺至开源社区。
-
在流领域,RocketMQ Streams 也是诞生于内部业务,当业务消息达到一定的规模后,低成本和轻量级的计算需求就呼之欲出了。
-
在事件领域,云原生时代带来了强烈的事件驱动需求,我们在云上孵化了全新的 EventBridge 产品并进行了开源。
从性能上来讲,延迟、吞吐量等这些,对比行业来说,是个什么水准,有没有相关基准测试数据?
一般讲性能,其实就是吞吐量和延迟两个指标。
对于吞吐量来讲,RocketMQ 在 2017 年就能优化到单机 50W 的 TPS,后续在内部甚至能摸高到 100W TPS,这个还是单条的性能(非批量),但实际上从生产环境的稳定性,以及业务消息的重要性来讲,我们从来没有在生产环境部署过这么高 TPS 的负载。如果是在批量的场景,行业各个消息队列我相信都能轻易地打满网络带宽或者磁盘资源。换句话说,性能是很难作为一个产品的核心竞争力的,除非是架构层面有限制,一般情况下差异都不大。RocketMQ 当前的性能是足够用的,即使是以高性能著称的 Kafka,在阿里云上 RocketMQ 都能作为其内核支撑阿里云 Kafka 的业务场景。
延迟就是一个非常重要的指标了,在延迟这个指标后面长尾延迟,也就是常说的毛刺更是重中之中,在线业务对于是 2ms 延时和 5ms 延时基本上都能接受,但非常难以接受的是经常性有秒级的毛刺。RocketMQ 曾经在内部双十一场景被诟病最多的就是毛刺,在 2016 年我们耗费了很大的精力打造了低延迟的存储引擎,非常顺滑地支持了这么多年的双十一,这也是 RocketMQ 能非常好地支持在线业务的一个主要原因。
除了这两点,弹性和可扩展能力也是非常重要的,单机性能再高,不能充分利用云上的弹性资源就不能算是云原生时代的解决方案。甚至从稳定性的角度来讲,控制单机的规格和性能上限,以横向扩展的方式支撑业务的弹性需求是更稳定更健康的一种方式。
对比消息系统整个的发展趋势,认为哪些地方的设计比较有先见之明?为什么?
这个问题我们简要回答,后续文章可以详细再说。主要有几个方面:
- 保持架构的简洁性:NameSrv+Broker 搞定一切需求,多副本技术能随意演进。
- 产品上的设计:轨迹、回放,都是业界首创和模仿的对象。
- 消息——>流的演进:单纯面向业务消息的场景,其实KV存储模型更适合,但 RocketMQ 一直坚持队列存储模型,也为后面向流存储方向发展留下了空间,同时也有了消息模型和队列模型共存的创新技术的诞生。
阿里云消息队列未来的规划是什么?
在新的浪潮下,我们认为消息队列会往以下三个方向进一步的演进:
-
第一个趋势是全面拥抱云原生,向上消息产品形态演进,支撑云原生应用架构(微服务、EDA)。比如微服务、事件驱动、Serverless 等现代化架构,向下消息系统自身进行云原生架构演进,要通过一系列的技术改造,充分释放云基础设施的弹性计算、弹性存储、弹性网络等能力,全方位提高消息的技术指标,降低成本,提高弹性能力。
-
第二个趋势是拥抱物联网。物联网技术将更广泛的落地到各行各业,万物互联、边缘计算进一步拓展消息的边界。面向物联网的消息队列要海量异构设备接入,海量消息队列存储,能够随处运行,具备云边端一体的无边界部署能力。
-
第三个趋势是拥抱实时数据。现在企业的数字化转型又往前迈进了一步。从原来的业务数字化迈进到了数字业务化,数字化企业持续产生业务数据,对业务数据的实时洞察、实时决策,能快速把握商机,指导业务获得更大的成功。消息队列也将从在线业务架构基础设施,延伸到实时数据架构基础设施,事务分析一体化。
在这个趋势的引领下,RocketMQ 当前和未来长远的规划一直是「打造消息、事件、和流一体的超融合处理平台」,RocketMQ 5.0 对这一目标完成了初步的布局,未来会进一步强化消息队列 RocketMQ 在这三个领域的进一步演进。
-
在消息领域,全面拥抱云原生技术,弹性伸缩,开箱即用。
-
在事件领域,产品形态全面升级,拥抱行业标准,让事件驱动架构无处不在,从单一业务的数字化系统,扩展到跨业务、跨组织的数字化商业生态。事件驱动架构同时也让云计算、云原生的技术能够更大规模的落地,提高云产品和用户业务的集成度,让 Serverless 技术被更大范围的采纳,为客户降本增效。
-
在流领域,流存储增强批量特性,大幅度提高数据吞吐量;新增逻辑队列能力,解耦逻辑资源和物理资源,在流场景也具备无缝伸缩能力;新增轻量流处理引擎,提供实时事件流处理、流分析能力。