当前位置: 首页 > 后端技术 > Java

RocketMQ5.0:存储计算分离新思路

时间:2023-04-01 19:25:57 Java

介绍:消息中间件RocketMQ虽然已经经历了阿里巴巴和开源社区十余年,但在云原生的浩瀚浪潮下,我们开始了解其架构RocketMQ有了一些新的思考。在本文中,我们将对其进行详细解释。作者|林青山来源|阿里巴巴开发者公众号ApacheRocketMQ自2012年开源以来,因其架构简单、业务功能丰富、扩展性强等特点,得到广泛采用。RocketMQ在阿里巴巴集团内部拥有数千台集群规模,每天十万亿条消息规模。在阿里云上,RocketMQ的商用产品也以弹性云服务的形式为全球数万用户提供企业级消息解决方案,广泛应用于互联网、大数据、移动互联网等领域的业务场景,物联网,成为业务发展的首选消息中间件。消息中间件RocketMQ虽然在阿里巴巴和开源社区已经存在了十几年,但是在云原生的浩浩荡荡的浪潮下,我们开始对RocketMQ的架构有了一些新的思考。痛点与难点阿里巴巴有大规模实践RocketMQ生产经验。RocketMQ自2016年对外商业化以来,以与集团消息中间件相同的架构,持续在云端为客户提供全托管消息服务。消息队列RocketMQ在云端已经具有相当的业务规模。随着业务的发展,这种极简的分布式架构逐渐暴露出云原生环境的一些弊端,比如运维成本增加、效率降低等。集团消息中间件通过存储计算一体化部署架构,为集团电商业务提供高性能、低延迟、低成本的消息服务。随着云的演进,云变得更加灵活,网络环境更加复杂,云原生时代对效率有了更高的要求。我们也迎来了将云上的消息架构向云原生转型的契机。上图是RocketMQ目前云端部署架构的简化版(只包含核心组件)。这种云上部署架构近几年遇到的主要痛点如下:01RocketMQ用户富客户端需要借助官方SDK使用云上的服务。这是一个重量级的富客户端,提供顺序消费、广播消费、消费者负载均衡、消息缓存、消息重试、位置管理、推拉整合等服务。、流量控制、诊断、故障转移、异常节点隔离等一系列企业级功能。RocketMQ的富客户端大大降低了集团客户的接入成本,帮助集团客户一站式构建高弹性、高性能的消息驱动应用。但是,云上的富客户端也有一些不足:富客户端与云端原有的技术栈不匹配,比如难以与ServiceMesh集成,也与新兴的云原生应用框架不兼容比如Dapr(?),consumer消耗大量的物理资源,对serverless的灵活性不是很友好;多语言很难使客户保持一致。云上多语言需求强烈,但富客户端逻辑复杂,团队没有足够的人力来保证多语言客户端的质量。为此,在云端诞生了基于GraalVM和HTTP协议的多语言服务器。LanguageSDK,但有其局限性;client并非完全无状态,存在内存状态,重启时会触发rebalancing,导致消费抖动和延迟。这种rebalancing的设计满足了性能需求,但是对于敏感业务来说,这些抖动可以说是在过去几年贡献了不少工单;分区级别的消费粒度,分区内客户端负载均衡的粒度,一个Partition不能同时被多个消费者消费,对慢消费者影响很大,不能通过分担慢消费者的压力产能扩张。02计算存储一体化Broker是RocketMQ的核心节点,承担了服务器所有的计算和存储逻辑。其核心能力为:计算:认证与签名、商业计量、资源管理、客户端连接管理、消费者控制治理、客户端RPC处理、消息编解码处理等。存储:基于分区的WAL存储、多类型索引(common,timing,transaction等),核心接收、发送、查询能力,多副本复制能力等。计算存储一体化的Broker具有以下优势:部署结构简单,开源用户可以脱离使用盒子;部署节点少,低成本支撑集团双十一万亿消息规模;数据就近处理,无中间环节,高性能,低延迟。但集成Broker在云环境也有其局限性:业务迭代效率低:发布单位为Broker,即使调整一行计量逻辑,也需要全部发布上千个Broker节点才能对整个系统生效网络,导致业务创新和迭代速度变慢。稳定性风险高:计算和存储是一体的,但大部分业务需求是针对计算逻辑,存储节点相对稳定,频繁的低值发布带来稳定性风险和运维成本;计算逻辑的每一次修改带来的释放都会带来缓存重构、消费延迟、客户端异常感知等问题。资源利用率低:Broker是磁盘IO和内存密集型应用,消耗的计算资源相对较低。但是两者融合之后,扩缩容也融合在一起,计算和存储节点不能单独做Serverless。Broker集群整体资源利用率低。控制环节复杂:由于数据和状态完全分布存储在Broker上,控制节点需要与各个Broker通信。例如,一个查询操作需要命中多个Broker并聚合结果等,导致控制链路逻辑复杂。03Client和Broker直连RocketMQ目前用户直接通过client与Broker通信,链路最短,运维简单,延迟低,但这种设计不能灵活适配云环境网络极其复杂,网络上有经典网络、VPC网络、公有网络,部署环境中有OXS区和销售区,将每个Broker节点暴露给客户带来运维负担:Broker不透明给客户端,客户端感知每个Broker节点,Broker的运维动作往往被客户端清晰感知;Broker直接对外提供服务,需要为每个Broker申请一个VIP,包括ClassicVIP、VPCVIP,甚至公网IP。其中数千个已在线运行和维护。贵宾。每个Broker都有几个VIP。在运维成本高昂的同时,VIP的手动申请长期阻碍了RocketMQ的自动化部署。无法支持多接入点,Broker通过NameServer暴露给用户,只能暴露一个接入点。一般情况下,用户只能选择经典网络、VPC网络、公网接入点中的一种。基于这样的背景,阿里云消息团队开展了专项计划,在云端升级RocketMQ的云原生架构,践行存储与计算分离的新架构,引入基于gRPC的全新多语言方案加速消息中间件的云原生化。存储计算分离的新思路如何在云端践行存储计算分离,如何探索适合RocketMQ三位一体的新架构,是RocketMQ云原生架构升级的主要考虑。有很多实际因素需要考虑:RocketMQ在阿里巴巴集团架构中的优秀特性得到了充分的验证。是否有必要将存储和计算分开来满足云的需求?由此产生的延迟和额外成本能否覆盖新架构带来的新价值?阿里云上的很多消息产品已经有了存储和计算分离的架构,比如消息队列RabbitMQ、消息服务MNS。新架构如何与这些产品架构集成?对于第一个问题,实践的结果让我们看到了架构简单的优势,但是在云上遇到的痛点也告诉我们,存储和计算分离势在必行。可见存储和计算要不要分开不是问题。也就是说,是否有可能在建筑上拥有所有的选择?对于这个问题,我们的解决方案是存储计算需要可分可合:“分”有两层解释,首先代表模块和职责明确,属于计算的逻辑应该包含在计算中模块,属于存储的逻辑应该下到存储模块;第二层是支持计算和存储分离部署。计算完全无状态,存储有状态,很好的解决云上多租户场景面临的各种问题。.“组合”的前提是代码设计必须先分开。至于是单独部署还是合并部署,完全是业务的选择。新架构必须支持合并部署形式,以满足吞吐量业务场景。比如阿里巴巴集团内部的超大规模消息流场景;或者在不需要面向服务的小规模单租户场景下,组合部署可以快速将RocketMQ投入生产。对于第二个问题,阿里云上有多个自研消息服务,协议标准不同。如何通过单一架构支持多种产品形态非常重要,能够将RocketMQ的核心业务消息能力无缝复制到多种产品中,放大业务价值。总而言之,架构层面的核心思想是从存储和计算架构分离入手,进一步探索单一架构下多产品的形态,减少消息子产品的冗余构建。最终还需要实现存储和计算可以分离和结合的部署形式。同时满足云端运维灵活,开源和企业集团部署简单高性能的需求。01存储计算分离架构RocketMQ5.0在架构上的第一个升级就是存储计算分离的改造。通过引入无状态的Proxy集群来承担计算职责,将原有的Broker节点逐步演化为以存储为核心的有状态集群。同时,将重新开发一批多语言瘦客户端,解决富客户端带来的诸多问题。上图是一个存储计算分离架构的简化图。该图借用了ServiceMesh划分控制面和数据面的思想和xDS的概念来描述。架构中各个组件的职责是:多语言瘦客户端,基于gRPC协议重构的一批多语言客户端采用gRPC,主要是考虑其在云原生时代的标准化、兼容性和多语言传输层代码生成能力。导航服务(NavigationServer)通过LBGroup暴露给客户端。客户端通过导航服务获取数据平面的接入点信息(Endpoint),然后通过计算集群Proxy的LBGroup收发消息。与通过DNS解析进行负载均衡路由相比,通过EDS暴露Proxy接入点信息可以做出更智能更精细的租户和流量控制、负载均衡决策等。NameServer是RocketMQ中原有的核心组件,主要提供broker集群发现(CDS))用于存储,用于存储单元Topic的路由发现(RDS)等,并为运维控制台组件、用户控制台组件、计算集群ProxyServe提供xDS。Proxy,一个重新开发的无状态计算集群,数据流的入口,提供认证和签名、商业计量、资源管理、客户端连接管理、消费者控制治理、客户端RPC处理、消息编解码处理、流量控制、Multi-Broker,原Broker模块的存储部分独立为一个新的存储节点,专注于提供极具竞争力的高性能、低延迟的存储服务,更容易加速存储能力的创新。存储和计算分离。原有Broker模块的计算部分逐步上移至Proxy集群。LB集团根据用户需求提供ClassicVIP、VPCVIP、InternetVIP、SingleTunnel、PrivateLink等多样化接入能力。存储和计算分离带来的额外成本主要是延迟和成本。关于延迟,存储和计算节点从本地方法调用切换到远程调用后,延迟不可避免地增加,通常在毫秒级。即使在阿里云上跨AZ网络通信,延迟也一般在2ms以内。对于大多数企业来说,延迟增加一个数量级是完全可以接受的。在成本上,存储和计算的分离不可避免地需要在网络传输层面、序列化和反序列化层面占用更多的CPU资源。但另一方面,存储和计算一个是磁盘IO和内存密集型,一个是CPU密集型。拆解后可以更好的设计规范,更好的利用碎片化的资源,更容易提升资源利用率。弹性容量,反而可以降低成本。总之,在云环境下,以云服务形式存在的RocketMQ非常适合存储计算分离的架构。02存储与计算相结合的架构但从本质上讲,存储与计算的分离与就近计算、就近存储的概念是相冲突的。存储和计算一体化的架构带来了云上的麻烦。本质是云是一个多租户的环境,在多租户场景下存储和计算的融合不够灵活。但是很多场景往往是小规模的单租户,其实更适合存储计算一体化。在开源场景下,开源用户期望RocketMQ是一个开箱即用、易于部署的消息中间件。存储计算分离架构会带来一定的复杂性,影响开源生态的构建。在集群场景下,数千台物理机的规模,存储和计算分离会带来额外的机器成本。在私有云场景下,很多私有云可能节点数量有限,更倾向于采用一体化架构。为了统一云外和云内的技术方案,我们期待一种存储和计算可以分离也可以结合的部署形式。分离部署意味着计算节点完全无状态,运维迭代极其简单。合并部署更原始。架构体验保持一致。但无论采用何种部署架构,存储与计算分离都是一种很好的模块化设计方式,必须进行编程层面的分离。如上图所示,左侧为云端单独部署形式,右侧为组合部署形式。合并部署时,计算节点可以作为存储节点的SideCar。采用网格思想进行部署,也可以将计算和存储结合起来。在同一进程中部署。实际上,在实践中,通过对代码的充分设计,Proxy节点可以通过构造函数构造出“Local”和“Cluster”两种部署形式,分别对应合并部署和分离部署两种架构形式。03单一架构,多种产品形态《云原生时代消息中间件的演进路线》文中提到,阿里云消息团队目前拥有业界最丰富的消息产品矩阵,包括消息队列RocketMQ、消息队列Kafka、微消息队列MQTT、消息队列AMQP、消息服务MNS,事件总线EventBridge。丰富的产品矩阵是团队多年来实践多元化、标准化演进的结果。目前所有的消息子产品都是基于RocketMQ存储内核构建的,这是非常以统一架构为前提的。通过单一的存储计算分离架构支持多产品业务形态是云原生消息探索的重要方向。这种单一架构多产品形态会带来很多好处,比如计算节点共建,通过模型抽象支持多种业务模型,多种通信协议,释放人力冗余建设等。通过将存储节点合并成池,各产品对接内部存储节点,形成资源池合并,统一运维和管控,有助于降低成本,提高效率,加速存储创新,孵化消息平台。如上图所示,单一架构多产品形态的核心,首先是统一存储和计算,进一步统一管理、控制和运维,真正做到一个架构可以支持多种云产品。存储集群足够抽象,可以满足一般的消息访问需求。计算集群一体化、充分模块化、可插拔,满足多产品部署带来的不同权限体系、不同协议、不同抽象模型的需求。综上所述,目前阿里云消息队列RocketMQ还处于实现存储计算完全分离架构的第一个过渡阶段,未来还有很长的路要走。我们将用至少一年的时间在公有云环境中全面实现存储计算分离架构,让Messaging服务更具弹性和云原生,让团队提升效率,加速业务创新。我们预计新架构能够稳定服务未来至少五年的业务增长。同时,存储和计算可分离可结合的部署架构,也能很好地支持不同规模开源用户的个性化需求,使ApacheRocketMQ开源社区成为一个整体。好处来自存储计算的可分离可重组架构的新形式。原文链接本文为阿里云原创内容,未经许可不得转载。