【跨国数仓迁移最佳实践5】MaxCompute近线查询解决方案助力物流电商等实时场景实现高效查询
本系列文章将围绕东南亚头部科技集团的真实迁移历程展开,逐步拆解 BigQuery 迁移至 MaxCompute 过程中的关键挑战与技术创新。本篇为第5篇,解析跨国数仓迁移背后的性能优化技术。
注:客户背景为东南亚头部科技集团,文中用 GoTerra 表示。
业务背景和痛点
印尼科技集团GoTerra是东南亚最具影响力的互联网巨头之一,业务覆盖网约车、电商、外卖、物流及金融支付。在迁移到 MaxCompute 之前,GoTerra使用的是GCP的核心大数据平台 BigQuery。BigQuery在多个方面展现出强大的产品能力,包括 SQL 语法适配、自动化迁移支持、流式写入、元数据升级以及智能资源调度等。
在GoTerra的众多业务线项目中,有三种使用场景对延迟要求极高:
- BI 报表场景:GoTerra的客户依赖大量的业务报表进行决策,这些报表对查询的响应速度和稳定性有较高要求,大部分场景要求查询结果在30秒内返回。
- 对客业务即席查询:在多个实时客户服务场景中,客服人员需要根据客户的不同需求,临时追溯大量历史数据以满足咨询和问题处理的需求。查询效率直接影响到服务质量和客户满意度。此前基于 BigQuery的方案,平均查询响应时间约为5秒。
- 数据流水线:这是支撑核心业务的数据自动化处理流程,下游业务高度依赖其输出结果,因此对性能有严格要求。大多数作业设置了30秒以内的超时阈值,确保任务高效稳定运行。
这些业务场景对MaxCompute的性能和稳定性提出了极高的要求。在整个迁移过程中,如何在性能上对标BigQuery成为了项目的核心挑战之一。
产品优势
为了满足用户在使用 MaxCompute 过程中对查询延迟和稳定性提出的高要求,特别是对标BigQuery的性能体验方面,MaxCompute 推出了近线查询解决方案 —— MaxQA(MaxCompute Query Accelerator)。
MaxQA在MaxCompute原有核心能力的基础上,进行了深度架构升级与优化。通过引入独享的管控层和查询计算资源池,也对管控层、连接协议、查询优化器、执行引擎、存储引擎、IO 链路及分布式缓存机制等进行了全面深度的优化。这些优化使得 MaxQA 能够实现更低的查询延迟、更高的并发能力和更强的系统稳定性,特别适用于 BI 报表实时刷新、交互式 Ad-hoc 分析以及近实时数仓等对响应速度和并发能力有较高要求的业务场景。
此外,MaxQA 兼容完整的 MC SQL 功能集,用户已有的 MaxCompute 上运行的 SQL 作业可以无缝迁移至 MaxQA,无需修改代码即可获得显著的性能提升。结合灵活的资源分时策略和弹性扩缩容方案,MaxQA 不仅提升了性能,还能帮助用户降低整体使用成本,实现性能与成本的双重优化。
技术方案概述
MaxQA整体架构介绍
MaxQA 整体架构图如下所示。
其中核心模块从上到下介绍如下。
BI 层,多款兼容了 MaxQA 的BI 工具,详见 MaxCompute 商业智能(BI)分析:https://x.sm.cn/7Ux4HN3。
管控层
- TopConsole:提供MaxCompute项目管理、Quota管理(包括 MaxQA 实例的管理)、租户管理等管理能力,同时提供作业运维及MaxQA 实例维度的可观测能力。
- DataWorks:MaxCompute与阿里云DataWorks深度结合,可通过DataWorks实现MaxQA 临时查询和定期节点的调度执行。
用户接口与接入层
- 用户可通过客户端、Java/Python/GO SDK 以及 JDBC连接到 MaxQA 实例。
- 接入层主要用于用户认证和向 MaxQA 实例转发作业请求。
MaxQA 实例层
- 由控制层、计算层和存储层三部分组成,其中控制层和计算层是实例级别隔离的,存储层是集群级别共享的。
MaxQA实例层架构介绍
一个MaxQA实例由若干台机器构成。每台机器具备CPU/内存/SSD存储等硬件资源。实例中所有机器的 CPU和内存总和等于用户所购买的CU(Compute Unit)资源。
每台机器配备的SSD存储,会用于构建实例级别的分布式缓存层和内存Spill池:
- 分布式缓存层
利用多台机器的SSD构成统一缓存池,缓存热点数据,提高整体效率;
- 内存 Spill 池
当SQL算子或ShuffleAgent发生内存不足时,可以将数据Spill到SSD中,避免OOM问题;
实例中包含了以下核心模块:
1. Coordinator
该组件是整个实例的访问入口,它包含多个核心模块:
- API 层:负责接收并响应用户的请求;
- SQLTask 模块:负责SQL语法解析、查询计划生成与优化、权限校验、源表Split以及算子 Codegen等操作;
- JobDriver 模块:负责根据生成的执行计划驱动作业的执行流程;
2. 预拉起Worker池
- 在实例创建时,系统会在每台机器上预先启动一定数量的Worker进程,每个进程集成了SQL执行引擎和存储引擎模块,为后续任务执行提供运行环境;
- Worker与Coordinator中的JobDriver紧密协作,依据物理执行计划驱动 SQL算子DAG,完成整个计算流程;
3. MaxQAAdmin
- MaxQAAdmin负责维护Worker池,并在实例热升级过程中,负责启动新版Worker并实现旧版 Worker 的平滑下线,确保升级过程中服务不中断;
- 当Coordinator驱动作业执行时,需向MaxQAAdmin申请所需的Worker资源。MaxQAAdmin根据预设的调度策略进行资源分配决策,以合理利用系统资源;
4. ShuffleAgent
- 该组件负责在 Task 上下游之间进行 Shuffle 数据的读取、写入和传输,支持跨节点的分布式数据交换,确保任务间的数据流转高效且可靠;
5. CacheAgent
- 在查询执行过程中,该模块负责实现数据缓存机制,缓存中间结果或热点数据,从而减少对底层存储的频繁访问,在保证数据一致性的前提下,显著提升查询效率并降低整体 I/O 成本;
MaxQA使用方式介绍
MaxCompute的Quota组分为一级Quota和二级Quota两个层级:
一级Quota是资源的顶层配额,按照付费模式可分为:
- 按量付费(后付费):根据实际使用量计费,适合不确定业务负载或有突发性需求的场景。
- 包年包月(预付费):用户提前购买固定时长的资源配额,通常成本更低,适用于稳定、可预测的业务场景。
包年包月类型的一级Quota可进一步划分为多个二级 Quota。包括:
- 批处理类型二级 Quota:主要用于执行周期性、大规模的数据处理任务,如 ETL、离线计算等。
- 交互式类型二级 Quota:用于支持 BI 报表、Adhoc 查询等对响应速度要求较高的交互式作业。
下图描述了各类型 Quota 提交作业的流程。
作业提交到指定的Quota组后,MaxCompute会根据Quota类型将任务分发至对应的资源池或实例执行。
预付费(包年包月)Quota:
- 批处理类型Quota:作业会被提交至MaxCompute的Serverless资源池中运行;
- 交互式类型Quota:每个交互式Quota组对应一个独立的MaxQA实例,作业将提交至该实例执行;
后付费(按量付费)Quota:
- 批处理类型Quota:作业会被提交至MaxCompute的Serverless资源池中运行;
- 交互式类型Quota:所有用户的交互式Quota组对应的都是由MaxCompute维护的同一个MaxQA实例,作业会提交至这个实例上运行;
更多使用细节,请参考:MaxCompute 官网-MaxQA接入方式。
MaxQA作业执行流程介绍
下图是批处理类型Quota组和交互式类型Quota组处理作业的流程对比。
图中展示了批处理Quota组与交互式Quota组在MaxQA中的作业处理流程差异,分别以黑色折线和橙色折线表示。以下是两种流程的描述:
批处理Quota组的作业处理流程
- 用户提交SQL请求
FrontEnd完成用户认证后,将SQL请求转发至控制集群的框架服务。 - 请求调度与流控
框架服务执行流控、排队等逻辑,并从SQLTask服务中任意选择一个进程进行处理。 - 生成执行计划并提交作业
SQLTask负责解析SQL并生成执行计划,随后将SQLJob提交至计算集群。 - 启动JobMaster驱动作业执行
计算集群启动JobMaster,负责在Serverless环境中申请worker资源并驱动该作业执行。 - 客户端获取查询结果
客户端发起查询结果请求。 - 请求路由与结果返回
FrontEnd 将结果请求转发至框架或Tunnel服务,由其读取查询结果并返回给客户端。
交互式Quota组的作业处理流程
- 用户提交SQL请求
FrontEnd完成用户认证后,将SQL请求直接转发至对应MaxQA实例的Coordinator模块。 - 生成执行计划并驱动执行
Coordinator模块负责生成执行计划并驱动作业在MaxQA的隔离环境中执行。 - 查询结果直接返回(小结果集)
如果是查询类作业且结果集较小,则查询结果会直接封装在客户端的响应中返回,无需额外的中间转发步骤。
MaxQA核心优化点介绍
MaxQA在独享的管控层和查询计算资源池的基础上,对查询接入方式、交互协议、查询优化器、执行引擎、存储引擎、IO 链路及分布式缓存机制等进行了多项优化,下面重点介绍一些核心优化。
独享的接入层和隔离的计算资源池
- 单租隔离
一个交互式Quota组即对应一个独立的MaxQA实例,各实例拥有独享的接入层与计算资源池,在架构上实现完整的资源隔离,避免多租户环境下的相互干扰问题。
- 查询直连
在单租隔离的基础上,MaxQA优化了查询接入链路,请求从前端直接转发至对应实例的Coordinator模块,显著减少查询提交路径的复杂度和延迟。
- 更精简的交互协议
针对执行时间在5秒以内且查询结果集小于10MB的查询,仅需一次请求即可完成查询提交与结果返回。
- 耗时链路异步化
将原本需要同步执行的 InstanceMeta/TaskMeta 等的写操作优化为异步进行,更快进入关键处理步骤。将作业运行成功以后的非关键操作(如 Summary 生成、Logview 展示结果生成等)优化为后台异步处理,不占用查询的E2E时间。
引擎优化
更优的并发度计算方法
- 结合实例可用资源计算各Vertex的并发度,最大程度避免并发度和资源错配导致的调度开销和资源闲置;
内存Shuffle模式优先
- 数据 shuffle 只会使用本实例内的 ShuffleAgent,拥有更高的稳定性;
- 优先使用内存Shuffle模式,内存不足时优先使用本机的 SSD,SSD 空间也不足时才依赖集群内的分布式文件系统;
SQL算子内存Spill优先本机 IO
- SQL算子执行遇到内存不足优先Spill至本机的SSD,SSD空间不足时才Spill至分布式文件系统;
Adaptive 选择执行模式
- 根据预估执行时间,自适应选择执行更快还是压缩率更高的压缩算法;
- 根据处理的数据量,自适应选择Codegen执行或列式执行;
下游预读模式
- 上游输出数据累计到一定比例,且没有其它作业等待执行时,下游节点会提前启动开始读取上游的输出,减少E2E延迟;
更优的管控层
- SQLTask和JobMaster合并到Coordinator模块中,减少组件间的通信开销与调度延迟;
- 源表Split操作、算子Codegen过程以及资源的初始化操作异步化;
全链路 Cache
- 元数据Cache:缓存表结构、分区信息、统计信息等元数据内容,减少远程Metastore的频繁访问,加快查询计划构建速度;
- 鉴权Cache:缓存同一用户对表、字段、资源、UDF等的权限校验结果,避免短时间内的重复鉴权操作;
- 源表Split结果Cache:缓存源表的Split切分结果,避免重复扫描文件系统,提升Split构建效率;
- 算子Codegen结果Cache:缓存SQL算子Codegen生成的动态库,避免相同算子重复编译;
- 源表数据Cache:自适应识别源表大小和访问频率,合适大小的源表在多次被读取时,会存到缓存中,减少对集群分布式文件系统的重复访问,缩短延迟的同时提高延迟稳定性;
- 查询结果Cache:缓存查询输出结果,重复查询再次执行时,直接返回缓存的查询结果;如果 Logview的JobDetails中出现如下形式,则代表本次查询命中了查询结果Cache。
- Shuffle结果Cache:智能分析实例中不同作业间存在的重复Shuffle过程,将这些Shuffle数据缓存,支持不同作业间共享Shuffle 数据,减少重复计算;
- 资源Cache:缓存UDF、外表handler等依赖的资源文件,避免重复下载;
灵活的弹性资源功能
定时伸缩计划
如果用户的交互式 Quota 组主要运行 BI 报表和 Adhoc 查询类作业,这类任务通常具有明显的时序峰谷特征。而用户购买的包年包月 Quota 组往往基于批处理作业的峰值需求进行配置,在非高峰时段常出现资源闲置、利用率低的问题。
通过 分时伸缩配置,可以根据不同时段灵活分配交互式与批处理 Quota 的使用配额,实现资源在时间维度上的动态调度,从而更高效地利用整体资源,降低冗余成本,提升资源利用率。
如下图所示,蓝色曲线表示用户购买的包年包月一级 Quota 组的 CU 数量。橙色方块代表交互式 Quota 组的 CU 配额,绿色方块代表批处理 Quota 组的 CU 配额。通过分时伸缩配置,系统会根据预设的时间段自动调整两个子组的 CU 分配比例,实现资源在不同时段的智能调度与高效利用。
弹性 CU
定时伸缩计划适用于用户已购买的包年包月 Quota 组中 CU 数量相对富余的场景,通过在不同时段灵活调整资源分配,提升整体资源利用率。
而对于 CU 数本身较为紧张,但在某些时段存在更高资源需求的情况,可以使用 弹性 CU 功能。该功能能够在指定时间段内自动动态扩展一定数量的 CU 资源,仅对这些临时弹出的 CU 使用量进行计费,从而在不增加长期成本的前提下,满足高峰期的计算需求,实现资源使用的灵活性与经济性之间的平衡。
如下图所示,蓝色曲线表示用户购买的包年包月一级 Quota 组的 CU 数量。橙色方块代表交互式 Quota 组的 CU 配额,青色方块代表弹性 CU 的数量。通过预设时段的弹性伸缩策略,系统会在指定时间点自动弹出相应的弹性 CU,并调整整体资源分配,实现资源在不同时段的灵活调度与按需扩展。
AutoScaling
定时伸缩和弹性 CU 功能均依赖用户提前配置生效的时间段,在面对突发的业务增长时,可能因预留资源不足而无法及时响应,导致任务堆积和等待。
为了解决这一问题,AutoScaling 功能应运而生。该功能能够实时感知 MaxQA 实例中的负载变化,并根据用户预设的扩缩容规则自动触发资源弹性调整,从而快速应对突发的资源需求,并按照实际使用的 CU 时长进行计费,在保障作业执行的稳定性和时效性的同时实现资源按需扩展与成本精准控制。。
如下图所示,在大部分时间段内,CU 使用曲线未超出交互式 Quota 的 MaxCU 限制。但在某些特定时段,使用量出现了明显增长,超出了当前配额范围。通过应用 AutoScaling 功能,系统可在这些高峰时段自动弹出一定数量的 CU 资源,满足突发资源需求。
✅ 注意:AutoScaling 功能目前尚未发布。
业务价值
MaxQA成功助力GoTerra多条业务线实现从GCP BigQuery到MaxCompute的平滑迁移。在整个迁移过程中,GoTerra用户对底层架构变更零感知,业务连续性未受影响,体验保持稳定。
在使用MaxQA后,GoTerra的核心业务场景性能得到了显著提升。相比使用 MaxQA 以前,整体查询效率提升了一倍,这不仅验证了 MaxQA 在高性能、低延迟和高稳定性方面的技术优势,也体现了其在大规模复杂业务迁移中的落地能力和用户体验保障能力。
未来展望
在性能提升方面,MaxQA将对执行引擎进行Pipeline多线程的架构升级,通过任务并行化和流水线式处理,显著提高查询效率和资源利用率。也会进一步优化调度开销,更好地支撑高并发、低延迟的业务需求。
在稳定性保障方面,MaxQA将构建主动识别异常作业的能力,并能够在发现异常后及时进行隔离,防止少量作业对整体实例的可用性造成影响。同时,MaxQA 将支持透明回退机制,在异常情况下自动将异常的任务切换至Serverless资源池,实现对用户业务连续性与作业性能的影响最小化。
在智能优化方面,MaxQA 将引入智能数据预热功能,根据实例中作业的历史运行情况,提前加载热点数据到缓存中。同时,系统还将提升Shuffle数据缓存的识别准确率,更高效地利用分布式缓存资源,进一步降低 I/O 压力,提高整体执行效率。
通过这些持续优化,MaxQA 不仅将进一步提升查询性能与系统鲁棒性,也将为用户提供更加智能、高效、稳定的一站式大数据查询体验,助力企业实现更敏捷的数据驱动决策。