基于 MQ 的分布式 Serverless 多租任务处理系统架构演进

本文涉及的产品
函数计算FC,每月15万CU 3个月
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 构建一个面向多租场景的 Serverless 异步任务处理系统面临多租隔离、资源需求多样化、任务管理等多种挑战该如何解决?快来查收这份异步任务系统构建实战一起学习吧!

本文作者:史明伟 , 阿里云智能高级技术专家。

1 Serverless 异步任务处理系统诞生和挑战

无论是对于云的开发者,还是尝试业务升级的企业客户,Serverless的三个概念 “极致弹性、无服务器运维、 按需付费” 几乎已经深入人心;但关于 Serverless能做什么、怎么做,却仍然是围绕在大家身边最普遍的声音。

图片

在Serverless研发的初始阶段,通常技术团队会更多聚焦于弹性,冷启动加速,希望通过弹性能力凸显产品技术竞争力,确立产品在市场上的领先地位,并依赖这些能力吸引开发者和企业客户使用Serverless,这个阶段,更多的是依靠技术影响力引导大家探索 Serverless。

随着我们对Serverless的不断深入理解,同时弹性能力的提升进入深水区,相对来说没有本质改变的情况下,我们将更多地思考触及Serverless弹性以外的其他价值,这个时候,弹性将作为系统的基础能力渗透在产品各个方面,需要更多的从系统性的角度考虑 Serverless能做什么,能给客户带来什么,如何让业务聚焦那些不得不需要定制化的部分?

系统性意味着我们需要从包括资源供给,弹性调度,应用框架,容量评估,运维观测等多个维度来考虑Serverless系统对于客户业务的价值, 哪些需要用户参与,或者少参与,哪些需要以服务化能力提供给客户;对于那些客户必须参与的,平台需要提供便利的开发工具满足开发阶段客户需求;在具体业务逻辑实现中,利用Serverless的灵活扩展性,尽可能快速的帮助开发者实现和其他云服务的快速连接,提供稳定高效访问是Serverless所能带给客户的核心价值。

面对实际的客户需求,产品需要考虑多种业务场景: 离线场景的耗时任务执行,在线场景的高并发请求处理,以及事件驱动场景的事件处理,如何将众多业务场景需求在一个计算平台上得到满足,是我们面临的最大挑战。

基于对 Serverless的不断深入理解,结合产品在弹性调度方面的不断积累,我们开始了基于多租架构的Serverless异步任务处理系统的构建,利用异步化的访问方式,帮助用户托管请求,以服务化的手段帮助用户快速执行任务,处理异常,提供可靠的执行保障,结合异步化的结果投递能力,希望能够面向事件驱动,在线业务处理,Serverless Job/Task 等复杂业务场景,为客户带来更多价值。

图片

构建一个面向多租场景的Serverless异步任务处理系统需要面临各种挑战;这个时候我们需要化繁为简,分析任务系统到底要做什么:任务分发, 任务调度, 任务执行。

Serverless本质是一个多租分时复用的商业模式,关于Serverless异步任务处理系统的挑战,结合任务处理系统的功能需求,这些挑战可以总结归类为三个方面:

第一,多租架构本身带来的挑战:包括租户隔离问题,多租资源管理,以及如何权衡隔离性和成本之间的矛盾,最后还需要关注多租架构下自动诊断,快速定位问题的挑战;

第二,业务类型多样性和资源供给之间的矛盾带来的挑战:资源需求多样化,客户可能需要多种资源,比如面向 CPU密集型、IO密集型、内存密集型等;运行环境多样化,客户运行业务逻辑时,需要为任务提供与其对应的运行环境,需要面对多种运行环境;运行时长不确定性,面对离线和在线场景的不同业务特征,实际任务的执行时长差异巨大;最后,不同业务类型流量特征不同,流量不可预知等问题带来的请求处理,任务调度和流控策略方面的挑战;

第三,任务管理本身需要面临的挑战:包括任务生命周期管理,运行操作、 任务去重,任务执行状态追踪以及任务结果投递等相关问题带来的挑战。

以上挑战也是企业在构建分布式业务系统时所面临的最核心问题,站在产品的角度,我们希望能够通过异步任务系统的构建,帮助用户解决分布式系统中的这些共性的典型问题。客户只需要关注自己的业务请求提交和执行结果,从请求提交到执行的过程中涉及的Serverless弹性能力,资源调度,系统流控及可靠执行,错误重试等细节无需用户关心,真正实现 Serverless 倡导的几个核心理念:极致弹性,无服务器运维、按需付费,最终帮助兑现Serverless对于客户的业务价值。

图片

在讨论了Serverless异步任务系统构建面临的多种挑战之后,通过上面的分析,Serverless异步任务处理系统功能可以简单概括为以下四个核心模块:

① 请求托管:负责多租架构的任务托管、用户请求存储、获取用户请求以及执行用户请求,如何在多组架构下选择合适的隔离粒度,更好的实现用户的请求隔离,如何在用户隔离需求的基础上更好的权衡隔离和成本之间的平衡。

② 流量控制:通常用户选择异步任务处理系统,大概率源于请求和消费之间存在矛盾。如何帮助客户解决用户请求以及后端资源供给之间的矛盾,更好地执行用户的任务请求,是异步系统核心所在,流量控制至关重要。

③ 执行管理:执行管理主要分为两个层面。首先,如何更好地执行任务,与流量控制更好的联动,如何用更好的方式调度资源从而更好地执行任务,这也是对系统底层调度的挑战。其次,如何管理任务请求,比如可能需要在任务执行过程中进行暂停、删除或批量操作,也需要对执行的任务提供状态追踪,了解其执行情况,并提供任务去重的能力。

④ 目标投递:也可以叫结果投递,需要将任务最终执行结果返回给用户。关于结果投递,这里有多个思考,一种是如何将结果投递;另一种是如何以更好的方式将结果投递;对于前者比较直观,而对于后者,我们希望对于任务执行结果,能够提供更灵活的再次处理能力,因此在实现上支持将结果投递到函数计算、MQ,EventBridge等更通用的产品上,用户可以基于这些产品再次利用事件驱动或相关能力对于任务执行结果进行后续的再次处理,包括发送短信、webhook 等,实现与异步任务系统进行上下游联动。

2 Serverless 异步任务处理系统多租户架构演进

下图展示了一个典型的异步任务处理系统的基本模型,通过 API 的方式进行任务提交、任务调度,任务执行,最后完成执行结果的投递。

图片

传统的任务处理框架中,通常会基于服务网关进行任务调度、负载均衡和流控策略等能力的建设,这也是分布式系统构建中最基本、但又最核心,最复杂,最需要人力投入重点建设的部分;后端实现通常都是基于进程粒度的内存队列和运行时层面的线程池模型完成具体的任务派发和执行。

Serverless 异步任务处理系统流程为:用户通过 API 的方式进行任务分发,请求到达Serverless服务网关之后,被存储到异步请求队列中,Async Service将开始接管这些请求,然后请求调度获取后端资源,将这些请求分配给具体的后端资源进行执行。该架构图中 Async Service负责了传统架构中请求Dispatcher、负载均衡,流控策略和资源调度的实现,这时候函数集群相当于抽象的分布式线程池模型,在函数计算模型下,实例之间相互隔离,且资源具备水平伸缩的能力,可以避免传统应用架构下单机资源限制导致的线程池容量问题及资源调度瓶颈问题,同时任务的执行环境并不会受整体业务系统运行时的限制,这也是Serverless异步任务系统相比传统任务系统的价值所在。

从Serverless任务处理系统的架构来看,其处理逻辑非常简单,大部分分布式系统依赖的能力全部由Async Service系统角色透明化的进行了实现,对于用户而言更多的是通过函数化编程的方式提供任务处理的实现逻辑,整体架构避免了对基于语言运行时线程池的依赖,整个函数计算集群提供了一个“无限”容量的“线程池”,通过服务化的方式,用户只需提交请求,其他并发处理、流控以及积压处理全部由 Serverless平台负责完成。当然在实际的执行过程中,需要结合业务特征对异步任务处理的并发度,错误重试策略及结果投递进行一些配置。

接下来,我们将重点讲述Serverless异步任务处理系统构建中的一些技术细节。首先我们从任务分发及请求托管开始讲述Serverless异步任务系统构建过程。

图片

Serverless多租架构下,异步调用请求首先到达系统的 API 网关,由API网关将接收到的异步请求放置到异步队列中托管;API 网关是一个无状态的架构设计,能够支持负载均衡和动态扩缩容。

简单的异步任务请求托管,在实际的系统实现中,不仅需要考虑租户之间的请求隔离,也需要考虑相同租户下不同函数之间的隔离需求;结合客观的请求隔离需要、请求处理的实时性要求,以及平衡队列资源的使用成本,我们设计了一套包含多种队列(Queue)类型,支持动态回收的队列管理系统,基于这样的系统实现满足了多租架构下隔离需求,执行效率,和隔离成本之间的平衡。

这些队列模型包括账号粒度的队列模型,函数粒度的队列模型以及多账号共享维度的队列模型;账号粒度的队列作为基本的执行保障,当队列中某个函数请求执行异常可能对其他函数请求产生影响的时候,会动态地为其分配函数粒度队列,并将该函数相关的请求路由到专属队列中进行处理;同时,对应的函数如果长期没有请求,在一定时间周期之后,会对之前分配的队列资源进行动态回收,达到队列资源的高效利用。

除了定义多种类型的队列模型之外,面对任务队列的切换,系统提供了任务请求的动态路由能力,可以自动化地将请求路由到不同类型的队列中,分发到不同的Partition上快速执行,解决由于Noise Neighbor问题引起的消费积压或请求负载不均带来的消费延迟问题。

有同学可能会疑惑,为什么不一开始给每个函数分配独立的请求队列?在云计算环境下,队列本身是一种资源,给每个账号下的每个函数分配一个Queue资源,看起来是彻底解决了请求的隔离问题,由于函数的量级和队列系统能够提供的队列量级是不对等的,考虑到下游系统的具体实现,结合底层为了满足实时性的消费处理逻辑,一个函数可能需要分配多个队列资源,通过并行消费多个队列满足请求处理的实施性要求,从实际来看,不仅要考虑Queue的分配性能,还需要考虑Queue资源分配对下游系统的冲击以及大量Queue资源本身的管理成本;每个函数持有一个Queue的成本也是巨大的,由于不同函数的负载不同,调用频率不同,为其分配独立的Queue在一定程度上本身就是一种资源浪费,与Queue密切相关的后端消费逻辑也会带来不必要的大量系统资源消耗,对于Serverless系统而言,这些都是非常巨大的系统资源浪费。

在讨论完请求托管的底层设计逻辑之后, 接下来我们将对于异步请求处理链路的流量控制策略做进一步的解释。

图片

流量控制主要包括两个部分,一个是面向任务请求消费的动态负载能力,主要是Receiver能力的动态扩容和缩容;另一部分就是后端任务执行调度的反馈能力,通过及时将后端任务处理的结果返回给Receiver ,再通过调整 Receiver 获取任务请求的速率,最终适配系统后端资源,达到平衡。

具体实现上,系统采用AIMD的反馈控制算法,即和性增长,乘性降低。该算法在 Serverless的高频请求或多租架构下,能够实现更细粒度的控制。整个过程可以将 Receiver和Invoker看作一个Pool,通过结合Pool Size线性增长以及遇到后端消费能力不足负反馈时 Pool Size 乘性衰减,使得 Pool Size 动态收敛到一个匹配后端处理能力的大小,实现系统的流控管理,避免上游请求的不断获取对下游资源调度的冲击,也避免了极端情况下由后端资源调度问题引起的系统饥饿状态。

图片

Job/Task模式下,业务对于Job和Task请求有追踪执行状态的需求,同时客户对于任务执行有一些高级管理,任务暂停,取消,任务去重等需求,我们在 Serverless异步任务的基本框架上增加了任务执行状态机的设计,通过引入状态机,可以对每个任务进行完整的状态追踪,可以基于状态追踪对任务执行进行细粒度的控制,也可以基于状态的控制实现异步处理的高级操作,比如任务删除、恢复、去重等高级任务管理功能,状态追踪也能够更好地体现任务生命周期的运行情况。

图片

一个任务处理系统不仅需要帮助客户完成任务请求和执行,也需要关注任务执行过程中的调试或任务执行状态和各种执行指标的查询。

 Serverless 系统为客户提供了非常完整的观测性能力,包括任务请求处理的情况、任务执行的耗时等,同时也提供了任务执行请求列表的查询,用户可以通过请求 ID 登录到正在执行的上下文,为用户提供了接近于传统操作习惯的过渡;此外,Serverless 系统实现了任务执行过程中生命周期各个阶段的耗时展示,为用户提供了从请求到执行完整的追踪能力。

3 Serverless 异步任务处理系统更大的价值

在Serverless异步任务处理系统中,用户的请求首先通过网关写入到异步队列中,异步队列本质是一个MQ, 异步任务处理系统本质是通过一系列的分布式消费策略,构建一个完整的Producer—Consumer模型,最终完成队列中每条请求的消费;将这样的系统模型进一步抽象,除了消费函数计算本身的异步请求,对于任何的MQ系统而言,都可以构造这样通用的消费处理层,也就意味着客户并不需要关注消费本身的系统实现逻辑,只需要提供对于消息本身的业务处理逻辑;EventBridge和函数计算的深度集成,正是通过这样系统化方式将消息消费与消息处理的逻辑进行分离,正如异步任务系统所做的那样,最终实现消息处理的Serverless化。

图片

按照新的Serverless消息架构, 用户无需自己实现消费端的实现逻辑,不需要关注和担心与消费相关的负载均衡及流量管理等分布式系统问题,针对消息的业务逻辑以及对下游数据状态的更改,客户只需要利用函数计算快速实现自己的业务逻辑,达到快速构建业务系统的目的,这也是Serverless面向消息场景,能够给客户提供的新选择。

在具体实现上,底层基于EventStreaming模式,消费组件直接从消息源处拉取消息,无需中间BUS层转存直接投递到目标函数,实现消息的高效处理;整体架构实现了将有状态的消息消费逻辑和无状态的消息处理逻辑进行分离。

图片

函数计算系统凭借其灵活的可扩展性和丰富的链接能力,能够快速帮助客户构建自己的业务系统;当然,这也对客户的业务系统构建提出了诸多的要求,例如需要按照函数编程范式进行代码开发,需要遵循函数计算运行模式,整体来看,客户需要基于Serverless架构对自己的业务系统进行一定的改造适配。

除了微观上提供的敏捷开发及灵活扩展能力之外,我们认为,函数计算系统真正的价值在于其整体的系统原子化能力,能够在宏观上作为客户系统在公有云环境的开箱即用扩展,使企业系统架构享受函数计算带来的资源弹性和灵活扩展能力。为了帮助企业利用 Serverless系统原子化的能力实现业务系统的延展,我们在 Serverless 的接入以及 Serverless 执行环境的支持上实现了更简单的接入方式。

请求提交层面,函数计算提供了HTTP接入方式,客户只需在自己的系统中集成函数提供的URL 即可将任务提交到公有云环境的函数计算引擎上。同时,函数计算构建了基于EventBridge的通用 PaaS 事件驱动能力,客户业务系统可以将相关事件投递到通用的基础设施上,然后通过EventBridge触发执行业务逻辑。

在业务系统的 Runtime 支持上, Serverless提供了多种接入方式,比如支持了传统的自定义镜像的运行。客户镜像无需进行任何改造,只需经过简单配置,即可将自己的任务和相关镜像托管在函数计算上,实现业务系统的快速接入,系统的灵活扩展和快速延展正是当下云原生架构所追求的目标。

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
2月前
|
消息中间件 存储 Java
RocketMQ(一):消息中间件缘起,一览整体架构及核心组件
【10月更文挑战第15天】本文介绍了消息中间件的基本概念和特点,重点解析了RocketMQ的整体架构和核心组件。消息中间件如RocketMQ、RabbitMQ、Kafka等,具备异步通信、持久化、削峰填谷、系统解耦等特点,适用于分布式系统。RocketMQ的架构包括NameServer、Broker、Producer、Consumer等组件,通过这些组件实现消息的生产、存储和消费。文章还提供了Spring Boot快速上手RocketMQ的示例代码,帮助读者快速入门。
|
16天前
|
机器学习/深度学习 编解码 人工智能
超越Transformer,全面升级!MIT等华人团队发布通用时序TimeMixer++架构,8项任务全面领先
一支由麻省理工学院、香港科技大学(广州)、浙江大学和格里菲斯大学的华人研究团队,开发了名为TimeMixer++的时间序列分析模型。该模型在8项任务中超越现有技术,通过多尺度时间图像转换、双轴注意力机制和多尺度多分辨率混合等技术,实现了性能的显著提升。论文已发布于arXiv。
138 83
|
3月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
3月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
5天前
|
设计模式 存储 算法
分布式系统架构5:限流设计模式
本文是小卷关于分布式系统架构学习的第5篇,重点介绍限流器及4种常见的限流设计模式:流量计数器、滑动窗口、漏桶和令牌桶。限流旨在保护系统免受超额流量冲击,确保资源合理分配。流量计数器简单但存在边界问题;滑动窗口更精细地控制流量;漏桶平滑流量但配置复杂;令牌桶允许突发流量。此外,还简要介绍了分布式限流的概念及实现方式,强调了限流的代价与收益权衡。
44 11
|
7天前
|
设计模式 监控 Java
分布式系统架构4:容错设计模式
这是小卷对分布式系统架构学习的第4篇文章,重点介绍了三种常见的容错设计模式:断路器模式、舱壁隔离模式和重试模式。断路器模式防止服务故障蔓延,舱壁隔离模式通过资源隔离避免全局影响,重试模式提升短期故障下的调用成功率。文章还对比了这些模式的优缺点及适用场景,并解释了服务熔断与服务降级的区别。尽管技术文章阅读量不高,但小卷坚持每日更新以促进个人成长。
33 11
|
9天前
|
消息中间件 存储 安全
分布式系统架构3:服务容错
分布式系统因其复杂性,故障几乎是必然的。那么如何让系统在不可避免的故障中依然保持稳定?本文详细介绍了分布式架构中7种核心的服务容错策略,包括故障转移、快速失败、安全失败等,以及它们在实际业务场景中的应用。无论是支付场景的快速失败,还是日志采集的安全失败,每种策略都有自己的适用领域和优缺点。此外,文章还为技术面试提供了解题思路,助你在关键时刻脱颖而出。掌握这些策略,不仅能提升系统健壮性,还能让你的技术栈更上一层楼!快来深入学习,走向架构师之路吧!
44 11
|
11天前
|
自然语言处理 负载均衡 Kubernetes
分布式系统架构2:服务发现
服务发现是分布式系统中服务实例动态注册和发现机制,确保服务间通信。主要由注册中心和服务消费者组成,支持客户端和服务端两种发现模式。注册中心需具备高可用性,常用框架有Eureka、Zookeeper、Consul等。服务注册方式包括主动注册和被动注册,核心流程涵盖服务注册、心跳检测、服务发现、服务调用和注销。
46 12
|
23天前
|
消息中间件 架构师 数据库
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
|
16天前
|
弹性计算 运维 Serverless
卓越效能,极简运维,体验Serverless高可用架构,完成任务可领取转轮日历!
卓越效能,极简运维,体验Serverless高可用架构,完成任务可领取转轮日历!

相关产品

  • 函数计算