前言
随着云计算、人工智能、物联网等新技术的应用普及,人类产生的数据呈现出了爆发式增长的态势,对数据处理的需求能力也提出了越来越高的要求。数据成了重要资产,收集、处理数据的能力成为了核心竞争力,比如:应用服务的运行监控,运营数据的分析,以及深度学习的数据过滤、预处理等,这些对已有数据的处理能力将直接影响服务的运营效率。我们可以使用现成的 ETL 系统完成上述目的,但是在很多情况下您可能希望自建服务。比如:
- 您的数据处理业务不定时运行,希望在无任务时,不消耗任何资源;
- 您的数据处理需求只有简单的几个步骤,"杀鸡焉用牛刀"?还是自建来的快点;
- 您的数据处理业务流程有较多的自定义步骤,但现成系统灵活性不足,自建才能满足业务需求;
- 您不希望消耗过多精力搭建和维护系统中使用的各类开源数据处理模块,但希望在大并发数据处理请求的场景下能够有较为良好的性能表现。
如果您有上述需求,或者希望实现一个 高度灵活、高度可靠、低成本、高性能 的离线数据处理系统,那么本文提供的 Serverless 技术方案将是您的最佳选择。
业务场景简介
场景:假设我们有一批待处理数据,数据的值为 data_1
或 data_2
。我们数据处理的目的是统计各类数据的出现次数,并将统计结果存储到数据仓库中。当数据量级达到一定程度,亦或数据源异构的情况下,我们很难一次性的通过一个进程在短时间内快速处理完成,在这种场景下,函数工作流 + 函数计算的组合提供了高效的解决方案。
在介绍方案细节前,先来了解下主要会使用到的两款产品:
- 阿里云函数计算 是阿里云基于事件驱动的全托管计算服务,通过极强的弹性、多语言的支持、丰富的工具链帮助用户快速搭建 serverless 服务,应对瞬时波峰并免去运维烦恼,让您专注于业务逻辑。
- 阿里云函数工作流 是阿里云分布式任务协同的全托管云服务,支持函数计算、自建服务(如 ECS 自建)等作为底层计算资源来实现您的业务编排。
为方便展示数据处理方面的核心能力,在数据仓库的存储方面,我们使用阿里云对象存储(OSS)来代表各种类型的数据库等作为基础存储设施。
下述方案将展示如何使用函数工作流 + 函数计算实现一个低成本高弹性的数据处理系统。在这个系统中,函数计算将根据数据量大小动态提供底层计算资源用于数据的处理、统计等工作,函数工作流将协助实现复杂业务上下游的逻辑编排。
具体方案
在一般的数据处理业务中,主要关注点如下:
数据源:需要处理的数据源。一般情况下,我们的数据往往来源于各类数据库、文本文件(日志文件)等;在本示例中,我们使用函数生成少量数据用作功能性的展示。在实际场景中,您可以使用各类自定义的数据源作为系统数据输入来源。
处理框架/模式:MapReduce,本示例中使用函数工作流实现
目的端:数据仓库。在本示例中,我们使用 OSS 作为数据仓库,即最终处理后数据的目的端。
数据处理流程:
我们首先将原始数据随机分成 3 -5 个 shards,每个 shard 中两种类型的数据都有。对每个 shard 先分别进行类型统计,并将中间结果存储(map)。最后,我们统一处理各 shard 的统计结果,对结果求和并存储最终结果(reduce)。业务流程如下:
- 从数据源获取数据;
- 对数据按照某种规则(或随机)划分 shard;
- 使用MapReduce(提高数据并行处理能力)对数据进行处理;
- 存储至最终目的源。
结合我们所使用的阿里云服务,系统的模块及交互关系如下图:
图 1
方案示例
您可从 github 获取本示例的全部代码。代码库中提供了一键搭建本示例全资源的工具,在使用前,请确保您已开通阿里云对象存储、函数计算、函数工作流服务。
资源准备
一键搭建示例工程使用了阿里云的 资源编排 ROS 工具。首先您需要配置好 ALIYUN CLI 工具 ,之后 clone 本项目后工程目录下执行下述命令:
aliyun ros CreateStack --StackName=etl-stack1 --TemplateBody "$(cat ./ros.yaml)" --Parameters.1.ParameterKey=MainAccountID --Parameters.1.ParameterValue={YourAccountID} --Parameters.2.ParameterKey=RandomSuffix --Parameters.2.ParameterValue=stack1 --RegionId=cn-beijing --TimeoutInMinutes=10
其中,请将 {YourAccountID}
替换为您的主账号ID。"stack1" 参数可以使用随机字符串等自定义参数。
执行该命令后,我们将创建以下资源用于本次示例工程:
访问控制 - RamRole
用于提供函数工作流的执行及函数计算的执行角色;
函数工作流
您可以从 demo-etl-flow.yaml 获取本文所用的流程示例。您可以在 函数工作流控制台 查看创建结果。
函数计算
示例工程会创建三个函数,执行上述命令后您可以在 函数计算控制台 查看创建结果:
- shards-spliter: 用于读取数据源,并依据某种规则对源数据划分 shard,将 shard 返回给工作流;
- mapper: MapReduce 框架中的 Map 函数。在该函数中针对传入的 shard 数据进行过滤、清洗、计算。往往一次数据处理流程中将会根据 shard 数并行生成多个函数实例提高数据处理速度。每个 map 函数处理结束后,结果将会被存储到 oss 的特定目录下;
- reducer: MapReduce 框架中的 Reduce 函数。在该函数中针对 map 的处理结果进行集成、合并,并推送最终结果至数据仓库(OSS)。
对象存储(OSS):
在本示例中对象存储将作为中间数据及最终数据的存储仓库。本示例会在 OSS 控制台创建一个名为 demo-etl-stack1 的 bucket。
系统原理及运行示例
本系统的关键部分在于 MapReduce 框架的实现。我们使用了函数工作流提供的 并行循环步骤 实现了根据数据 shard 数量动态创建 Map 实例的功能。在 shards-spliter.py 函数中,我们随机对数据进行了 shard 划分,并将划分结果返回给流程,在下一个并行循环步骤中,流程获取 shards-spliter.py 中的输出,并行创建了多个实例进行对应 shard 数据的计算。在最后一个步骤中,reducing.py 读取 OSS 中的中间结果进行聚合后,将最终结果存储至 OSS。
运行示例及执行结果:
小结
本文介绍了在 ETL 等离线数据处理场景下使用函数计算(FC)、函数工作流(FnF)实现无服务化的解决方案。您可以充分享受到 Serverless 所带来的高弹性、免运维、轻量化等技术红利,专注业务场景,快速实现业务价值。
知识链接
函数工作流:函数工作流文档,官网客户群(钉钉):23116481
函数计算:函数计算文档,官网客户群(钉钉):11721331
欢迎加入函数计算、函数工作流官网客户群,与我们共同交流 Serverless 技术。