前言:本文整理自 RocketMQ x EventMesh OpenDay 金融通演讲内容
作者 | 金融通
今天分享的主题是云原生消息事件流超融合平台 RocketMQ 5.0 初探,内容主要分为三个部分:
首先,带大家回顾业务消息领域首选 RocketMQ 4 发展历史以及 4.x 版本的演进与发展。
其次,会为大家详细介绍 RocketMQ 5.0 发展情况以及一些新特性。
最后,会为大家介绍 RocketMQ 5.0 的发展路线图,方便社区小伙伴能够一起参与进来到 5.0 的贡献中来。
RocketMQ 发展历程
RocketMQ 自诞生以来前后经历了四代架构,并伴随着企业IT 架构不断发展,从 SOA 时代到微服务时代,再到如今的云原生时代。RocketMQ 最早诞生于阿里巴巴,阿里巴巴早期有一些自研的消息引擎,比如淘宝的 Notify、B2B 业务的 Napoli。但无论是 Napoli 还是 Notify,都是基于关系型数据库进行存储并带来了一些隐患。
所以在2011年,阿里巴巴以文件系统作为存储研发了 MetaQ。经过不断探索,在重写 MetaQ 2.0 后,第一代 RocketMQ 正是诞生,并将其命名为 RocketMQ 3.0 。2013年,阿里巴巴对 RocketMQ 进行开源,并在2016年捐献给 Apache 社区。2017年,RocketMQ 从 Apache 毕业,正式成为 Apache 基金会*开源项目。
随着 RocketMQ 进入 Apache 基金会,RocketMQ 4.x 进行快速发展,也发布了非常多版本,在架构多副本能力、消息类型、消息治理方面都有了非常巨大的飞跃。与此同时,社区生态也茁壮成长,全球 Contributor 数接近 500 人。
伴随着云原生时代到来,以及实时计算的兴起,RocketMQ 也将进行全面升级,发布 RocketMQ 5.0。我们和社区小伙伴们将 RocketMQ 5.0 定义为云原生的消息、事件、流的超融合平台。
RocketMQ 4 回顾
回顾 RocketMQ 4,我们一直在强调 RocketMQ 是业务消息首选。非常多公司将 RocketMQ 用于核心交易链路上,甚至很多公司会搭建两套消息系统,一套 Kafka 进行数据分析,另一套 RocketMQ 用于业务消息处理。
那为什么 RocketMQ 会为成为众多企业的一致选择呢,从以下几点,也许能一窥究竟:
第一,RocketMQ 是金融级高可靠的产品。相比于其他消息中间件,RocketMQ 经过超大规模验证。阿里巴巴几乎所有消息链路都是建立在 RocketMQ 之上,包括核心交易链路。比如双十一当天 RocketMQ 支持了超过数万亿条消息的流转,与此同时,在阿里云上的消息服务也服务了数万家企业。这些规模庞大的企业对 SLA 同样有着极高的要求。而这些自身实践以及客户服务的大量真实场景打磨对于消息系统的稳定性起到了至关重要的作用。
第二,RocketMQ 有着极简的架构并且易于维护,整个集群由 NameServer、Broker 两部分组成,NameServer 进行路由发现,Broker 作为实际存储数据的集群。从架构图中可以看到,RocketMQ 采用两主两备的集群方式,从节点通过同步复制或者异步复制的方式向主节点同步数据。这样的部署模式保证了服务能够具备较高可用性。
通过部署多组 Broker,即使其中一组 Broker 的 Master 出现不可用,也可以发送消息给其他组 Master,Consumer 也能从 Slave 进行读取。而 NameServer 处于完全无状态,即使 NameServer 全部宕机,由于客户端已保存路由信息,所以也不会影响存量服务。此外,RocketMQ 的运维也非常容易,扩容时只要增加 Broker 组数即可。如果一组 Broker 出现问题,也可以将它进行禁写,路由会马上被摘掉,不会影响其他业务。
RocketMQ 部署也非常简单,JAR 部署只需要两行命令就能把 RocketMQ 进行拉起。在 K8s 上部署就更加简单,如果用了 RocketMQ Operator ,用一句 kubectl apply 命令就能将整个集群拉起来。
第三,是丰富的消息类型,RocketMQ 支持普通消息、顺序消息、延迟消息、重试消息、死信消息、事务消息等。在消息治理方面,RocketMQ 除了常见的订阅模式,广播模式、集群模式,还支持消息查询,消息回放,消息轨迹,ACL 权限控制等。此外,RocketMQ 也是业界少有的原生支持服务端过滤的消息产品,可以提供给用户更加丰富的使用场景,也可以充分利用服务端计算资源。RocketMQ 不仅支持消息的 Tag 过滤,还创新性地支持 SQL92 过滤,Tag 过滤其实已经满足了绝大部分的过滤需求,如果特别复杂的场景可以考虑 SQL92 过滤方式,两个过滤方式基本上可以满足所有消息过滤需求。相比于其他消息中间件而言,RocketMQ 的消息类型和消息治理是最丰富的。
最后 RocketMQ 具备高吞吐低延时的特性。在阿里巴巴双十一中,RocketMQ 支撑万亿级洪峰并保持毫秒级响应。
接下来,带大家回顾一下 RocketMQ 4.x 版本的发展。在开源早期,RocketMQ 就已支持普通消息、顺序消息、延迟消息等不同类型消息,基本满足大多数业务场景。
在 RocketMQ 4.3.0 版本之后,正式发布事务消息,通过类似于两阶段的方式去解决上下游数据不一致问题。
在 RocketMQ 4.4.0 版本中,RocketMQ 增加了消息轨迹的功能,使用户可以更好定位每一条消息的投放接收路径,帮助问题排查,另外还增加 ACL 权限控制,提高了 RocketMQ 的管控能力和安全性。
在 4.5.0 版本中,RocketMQ 推出了多副本,也就是 Raft 模式。在 Raft 模式下,一组 Broker 如果 Master 挂了,那么 Broker 中其他 Slave 就会重新选出主。因此 Broker 组内就拥有了自动故障转移的能力,也解决了像高可用顺序消息这样的问题,进一步提高了 RocketMQ 的可用性。
在 4.6.0 版本中,我们推出了轻量级 Pull Consumer,用户可以使用更加适合于流计算的 API,这一版本也开始支持全新的 Request-Reply 消息,使得 RocketMQ 具备了同步调用 RPC 的能力,RocketMQ 可以更好的打破网络隔离网络之间的调用,这个版本中 RocketMQ 也开始支持 IPV6,并且是首个支持 IPV6 的消息中间件。
在 4.7.0 版本中,RocketMQ 重构了主备同步复制流程,通过线程异步化,将同步复制和刷盘的过程 Pipeline 化,同步双写性能有将近数倍提升。
在 4.8.0 版本中,RocketMQ Raft 模式有了一个质的提升,包括通过异步化、批量复制等手段将性能提升了数倍,在稳定性上利用 OpenChaos 完成包括宕机、杀死进程,OOM、各种各样的网络分区和延迟的测试,修复了重要 Bug。在功能上,支持 Preferred Leader,从而 Broker 组内可以优先选主,也支持了批量消息等功能。
在 4.9.0 版本,主要是提升了可观测性,包括支持 OpenTracing,事务消息和 Pull Consumer 支持 Trace 等功能。
可以看到 RocketMQ 在经过多年发展,从性能、稳定性、可靠性、可观测性等方面都有了很大提高。并且在这一过程中,除了阿里之外企业在代码建设方面做出了卓越贡献,这也证明 RocketMQ 已成为多元化并繁荣发展的社区。
除了 RocketMQ 主仓库的发展,RocketMQ 生态项目发展也令人备受鼓舞,特别是与云原生热点技术的整合,比如说在云原生化部署上面,我们有 RocketMQ Operator、RocketMQ Docker 这些项目。在微服务开发框架上面,RocketMQ 社区也通过构建 RocketMQ Spring Boot Starter 这种接入方式,方便开源用户的微服务系统与 RocketMQ 消息队列的通信能力能够实现快速集成和打通,以此为基础 Spring Cloud Stream Binder 和 Spring Cloud Bus 的 RocketMQ 实现也被 Spring Cloud 官方收录。
在 Service Mesh 方面,RocketMQ 是最早和 Envoy 结合的消息产品,现在也完成了 Dapr 的集成。在 Serverless 方面,包括适配 Cloud Events 以及社区开源了 RocetMQ Knative Source 仓库。
在可观测性上,RocketMQ 支持 OpenTracing、OpenTelemetry、Prometheus Exporter 等 。
在 Eventing 领域,我们有自己的 RocketMQ Connector,可以去完成各种外部组件,比如 MySQL、ElasticSearch 与 RocketMQ 的数据交互和数据同步,也能完成 MQ 集群之间的一个数据流转。在 Streaming 领域, RocketMQ 5.0 会发布原生的轻量级实时计算框架 RocketMQ-Streams,另一方面 RocketMQ 也积极和 Flink、Storm 、Spark 等现有大数据框架进行集成。
我们可以看到 RocketMQ 不仅是业务消息的管道,也在承担着事件流转、业务数据的一些离线计算和轻量级的实时计算。通过消息、事件、流三个方面发展,RocketMQ 已形成完整自闭环的生态发展,正在逐渐成为消息、事件、流的超融合的处理平台。
RocketMQ5.0 概览
在正式介绍 RocketMQ 5.0 之前,我们需要先回答这样一个问题:为什么我们需要 RocketMQ 5.0,在跟众多贡献者沟通以及对 RocketMQ 大量运维实践后,发现这里有两大原因:
首先,开源社区的需求越发凸显,当大量企业采用 RocketMQ 后,每个用户都有丰富的业务场景。而 RocketMQ 4.x 主要服务于业务消息领域,那么如何通过 RocketMQ 进行实时数据计算去处理这些高价值数据,成为企业下一步探索的重要方向。这也是 RocketMQ 为什么会从消息领域去积极拓展流计算领域的原因。
其次,云消息服务质量要求不断提高,作为 RocketMQ 深度参与者与贡献者,阿里云的消息服务目前已服务数万家企业。随着客户企业对于服务的要求,以及阿里巴巴自身的业务发展,这都对 RocketMQ 有了更高要求。如何做到一套架构,同时能满足不同用户不同场景需求,成为 RocketMQ 5.0 中重点解决的问题。
因此,结合广泛的实际业务场景,RocketMQ 5.0 作为生于云、长于云的全新的架构,经过不断探索实践,RocketMQ 5.0 主要具备以下特性:
1. 高 SLA、低成本:与云一致的可用性、高性能、低成本
2. 可调度:任意组件的重塑与组建适应多样性场景
3. 可扩展:开放的丰富生态
4. 可伸缩性:极致自动化扩容/缩容
5. 标准化:社区标准,符合行业标准
RocketMQ 5.0 作为云原生的消息事件流的超融合平台,基于架构图我们一一进行讲解:
1. 轻量级 SDK
RocketMQ 5.0 提供轻量级的客户端,使之具备良好的集成与被集成能力。同时,将负载均衡、逻辑位点管理这些复杂逻辑都放到服务端,实现无状态化。在协议选择方面,除了原有协议之外,全面支持云原生通信标准 gRPC 协议。
2. 极简架构
RocketMQ 5.0 依然不会去引入任何外部依赖,保持极低的运维负担。同时,节点之间的松散耦合,任意服务节点可以随时进行迁移。RocketMQ 5.0 将会是面向失败的设计,任意的服务节点的失败和迁移都是可以忍受的。
3. 可分可合的存储计算分离架构
Broker 节点会成为真正无状态的服务节点,并且没有 Topic Banding。也就是说消息的发送和消费是可以发生在任意计算节点上,一个接入点即可代理所有流量,计算层以及存储层均可独立进行弹性扩缩。在存储计算分离后,计算节点可以处理不同类型的协议,包括 Remoting、gRPC,MQTT、AMQP 等。此外包括 ACL、订阅关系、多租的控制等都会放在计算节点上。最重要的一点,它是可分可合的,可以支持小集群,也可以支持超大规模的集群,并且能适应多种业务的场景,降低运维的负担。
4. 多模存储
RocketMQ Raft 模式采取三副本形态,与本身就拥有三副本的云盘结合之后,相当于就得到了 9 副本。9 副本虽然带来了更高的可靠性,但也造成了严重的成本浪费。所以,RocketMQ 5.0 通过多模存储解决这一问题。比如,在普通的块存储设备上,可以根据可用性需求完成两副本或三副本部署。在云上用单副本,从而更好的支持云盘输出,充分利用云上基础设施去降低运维成本。
5. 云原生基础设施的广泛使用与整合
支持 OpenTelemetry、Prometheus 等项目,强化 RocketMQ 可观测能力。并更好去支持 K8s 生态,比如 RocketMQ Operator 用一条命令即可拉起 RocketMQ 集群,并且去完成向灰度发布数据的全生命周期管理,自动弹性扩缩等方面的支持。
核心特性一:可分可合的存储计算分离架构
接下来,详细介绍一下可分可合的存储计算分离架构。可分可合指的是 RocketMQ 可以像现在一样用同一进程去启动 Broker,也可以分开部署。分开部署之后计算节点就能真正的做到无状态,RocketMQ 对存储计算分离的架构的引进是非常谨慎的,一体化部署带来了诸多好处,比如大数据场景下,一体化部署提供就近计算能力,降低带宽成本。业务消息场景下,一体化部署可以降低延迟。与此同时,存储计算分离也有非常多的好处,比如说扩缩容可以更加灵活,可以针对具体计算资源或存储资源进行扩缩容。
因此 RocketMQ 5.0 将会提供可分可合的存储计算分离架构,可以适应多种场景。计算节点是完全无状态的。包括像协议适配、流量租户等管控都会放在计算节点上完成。此外,通过 POP 消费方式把整个客户端的负载均衡逻辑位的管理上升到计算节点,无 Queue Binding,任意的计算节点都能进行收发。另外,由于无状态,可以完成秒级弹性扩缩,并且过程中是没有 Rebalance 负担的。
与此同时,RocketMQ 5.0 会对存储集群进行了优化调整。在存储集群中我们原生的保留了多消息类型的存储支持,包括事务消息、定时消息,重试消息、死信消息等。在副本的选择上,根据不同场景去提供不同支持,包括本地块设备多副本支持、云盘单副本支持。借助多模态存储功能,充分利用云上基础设施降低成本。
另一点非常重要的是多元索引的支持。现在 RocketMQ 存储是一份 CommitLog ,后台线程去分发构建 ConsumeQueue、index 这些索引。那么 RocketMQ 5.0 会对索引全面增强,支持更多样索引。比如加入批处理的索引,消息就可以完成批量发送,批量存储,批量接收,从而提升 RocketMQ Batch 能力。比如消息队列只做消息轮转,查询能力比较弱,在 RocketMQ 5.0 中,消息和 KV 会更好结合在一起,去构建查询索引从而增强 KV 能力。通过一份数据,多种索引,RocketMQ 5.0 可以满足不同场景。
核心特性二:流批一体的数据访问方式
首先介绍全新的消费模式——POP 消费方式。左上角的图是 RocketMQ 4.0 现有消费端的负载均衡架构。比如现在 Topic 分布在 3 个 Broker 上,共计 9 个队列。在集群模式下,1 个消费组有 3 个消费者。根据。所以每个消费者分配到了三个队列。
但这也带来了一些问题,比如说某 Consumer 突然 Hang 住了,这它无法消费消息但也没有掉线,仍然保持和 Broker 的心跳连接,因此也不会将剔除而进行重平衡,所以这个消费者分配到的队列就会有大量的消息堆积,这些队列的消费就会卡住。
这本质上是一个绑定关系问题,一旦 Rebalance 发生后,Consumer 和队列就完成了绑定。针对这个问题,RocketMQ 5.0 推出了一个全新的消费方式,即 POP 消费方式。它取消了 Rebalance 造成的绑定关系,一个队列可以被任意多个 Consumer 进行消费,然后在 Broker 端通过队列锁完成并发控制。
POP 消费中,客户端会直接到每个 Broker 的队列进行请求消费, Broker 会把消息分配返回给等待的客户端。随后客户端消费结束后返回对应的 ACK 结果通知 Broker,Broker 再标记消息消费结果,如果超时没响应或者消费失败,再会进行重试。
Broker 对于每次 POP 的请求,都会有以下三个操作:
1. 对应的队列进行加锁,然后从 Store 层获取该队列的消息;
2. 然后写入 CK 消息,表明获取的消息要被 POP 消费;
3. 最后提交当前位点,并释放锁。
CK 消息实际上是记录了 POP 消息具体位点的定时消息,当客户端超时没响应的时候,CK 消息就会重新被 Broker 消费,然后把 CK 消息的位点的消息写入重试队列。如果 Broker 收到客户端的消费结果的 ACK ,删除对应的 CK 消息,然后根据具体结果判断是否需要重试。
从整体流程可见,POP 消费并不需要 Reblance ,可以避免 Rebalance 带来的消费延时,同时客户端可以消费 Broker 的所有队列,这样就可以避免机器 Hang 住而导致堆积的问题。
有了 POP、PUSH、PULL 等模式之后,RocketMQ 就可以完成流批一体的数据访问方式。比如说在 Streaming 场景下,通过原本 PUSH 方式可以保证很好的顺序消费。但批处理等对顺序要求并不高的场景中,我们可以用 POP 消费的方式对同一队列进行高并发读取,加快数据读取速度。另一方面 POP 消费模式也使得客户端更加轻量化,大量的逻辑都在服务端,对多语言客户端的编写也是更加友好的。
核心特性三:极致弹性扩缩
上图是 RocketMQ 现有架构,比如说我们通过禁写操作,可以使 Broker 1001 的流量自然流入到 1002 上。但在 Streaming 领域,上层业务一般要求存储队列始终固定的,只有这样才能保证流式数据处理的顺序性和完整性,这也就要求扩缩容不会引起队列数量的变化。因此 RocketMQ 5.0 Preview 版本提供了一个逻辑队列概念,把原本的物理队列逻辑组合在一起,一个逻辑队列可以分散到不同 Broker 上面。比如图中的一个逻辑队列,0~100 在 Broker 1001 上,100~1000 在 Broker 1002 上,1000~2000 的在 Broker 1003 上,通过组合可以把多个物理队列串联成了一个大的逻辑队列。
由于逻辑队列是一个 Binding 过程,所以是非常轻量级的操作,因此提供了一个秒级弹性扩充的一个能力,过程中完全没有也没有数据的复制,只要一完成 Broker 扩容,完成绑定操作,流量也就完成了调拨。另外我们也提供双模队列兼容的能力,平时默认还是原来的物理队列,只有指定单个 Topic 开启后,才会使用逻辑队列。
核心特性四:轻量级实时计算
RocketMQ 5.0 中还有一个非常重量级的特性,将会推出轻量级的实时计算框架 RocketMQ Streams。它的设计目标是帮助用户在不依赖外部重量级计算产品的情况下,仅利用已有 RocketMQ 资源完成大多数业务场景需要的轻量级的数据处理和计算。
RocketMQ Stream 依赖少、部署简单,它利用 RocketMQ Rabalance 能力可以任意横向扩展,同时支持包括 Map、Fliter 这些常见的算子,还有 Window、Join、维表等。另外相比于其他基于消息的实时计算平台,RocketMQ Streams 除提供原生无依赖的支持外,可以兼容 Flink SQL 标准以及提供 UDF/UDAF/UDTF 的能力。
另一方面,在实时计算生态上面,RocketMQ 也积极的和其他的大数据框架进行对接,包括 Flink、Spark 等 。特别是基于最新标准的 RocketMQ-Flink Connector 也会近期毕业。
RcoketMQ 5.0 Landscape
RocketMQ 5.0 版本将在今年正式发布, 5.0 Preview 的版本已经在 Discuss 了,代码也放在 Github 仓库中,5.0 Preview 版本会推出逻辑队列,以及流批一体的访问方式等重磅特性。之后我们会正式发布实时流计算框架 RocketMQ Streams,并在 RocketMQ 5.0 支持批处理、批索引能力。在后续的里程碑中 RocketMQ 5.0 将会完成 gRPC 协议支持,全新的轻量级客户端,完成 AMQP、MQTT 协议等支持,以及可分可合的存储与计算分离架构。
也希望能有更多的小伙伴参与到 Apache RocketMQ 社区中来,一起打造来下一代云原生消息引擎,打造 Messaging、Eventing、Streaming 的超融合处理平台。