Amazon Glue ETL 作业调度工具选型初探

2a8fc75a3ddda56ee52f3754c733a0b9.gif

Amazon Glue 是一项完全托管,无服务器架构的ETL服务。客户无需预置基础设置,仅需由 Glue 负责预置、扩展 Spark 运行环境,客户只需要专注开发 ETL 代码,并且使用 Amazon Glue 时,只需为 ETL 作业运行时间付费。

介于 Amazon Glue 的诸多好处,很多客户考虑将现有 ETL 任务迁移到 Amazon Glue 上,然而,如果发现原先使用的ETL任务的编排工具和 Amazon Glue 并没有很好的集成,在迁移过程中就需要对编排工具重新选型。Amazon Glue 作为一种新型的 ETL 服务,任务编排的选型上有诸多选择,例如:

  • 亚马逊云科技原生编排服务 Amazon Step Functions

  • Amazon Glue 原生的编排功能 Glue Workflow

  • 数据工程中流行的 Apache Airflow

本文就编排选型,如何实现自动化迁移工作流,减少开发人员适配工作上做一定的探索。

使用 Amazon Glue Workflow 编排任务

Amazon Glue 原生提供 Glue Workflow ( Amazon Glue 工作流)作为 Amazon Glue ETL 任务的编排服务。Amazon Glue Workflow 提供可视化界面,可以方便地创建基于 Amazon Glue 任务的工作流,在 Amazon Glue 工作流中指定作业、爬虫程序(Glue Crawler)和触发器。工作流可以按需或者按指定计划运行。

然而,在迁移现有 ETL 工作流,尤其是复杂的 ETL 工作流时,在可视化界面上一一重新定义并不现实。这时候就需要有自动化手段进行迁移。和其他亚马逊云科技服务类似, Glue Workflow 的代码化定义有几种方式:

  •  Amazon Glue 服务的 API/SDK

  •  Amazon CloudFormation

  • Amazon CDK(Cloud Development Kit)

以常见的 Azkaban 工作流为例,Azkaban 可通过 API 导出现有工作流的 JSON 描述文件,示例如下。

[
  {
  "project" : "azkaban-test-project",
  "nodes" : [ {
    "id" : "test-final",
    "type" : "command",
    "in" : [ "test-job-3" ]
  }, {
    "id" : "test-job-start",
    "type" : "java"
  }, {
    "id" : "test-job-3",
    "type" : "java",
    "in" : [ "test-job-2" ]
  }, {
    "id" : "test-job-2",
    "type" : "java",
    "in" : [ "test-job-start" ]
  } ],
  "flow" : "sample-workflow-by-cdk",
  "projectId" : 192
  }
]

在上述 JSON 描述文件里,每个 node 是一个任务,而每个节点的依赖任务则定义在”in”中。针对这样的任务关联描述,我们选用 Amazon CDK 的方式部署 Glue Workflow,因为使用 CDK 可以用代码化的方式生成 Amazon CloudFormation 模板,而不需要在模板里手动填写每个任务的依赖关系,从而减少开发人员的工作量。并且,当修改 JSON 描述文件时,比如增加或者删除一个任务依赖时,只需要重新运行 CDK deploy 就可以更新 Amazon CloudFormation堆栈, Amazon CloudFormation 可以自动生成 Changeset 更新,将提交的更改与堆栈的当前状态进行对比,然后仅更新更改过的资源。

使用 Amazon CDK 部署  

Amazon Glue ETL 任务和工作流

如果没有在客户端安装过 CDK,可以参照 Amazon CDK 文档安装。

git clone https://github.com/yizhizoe/glue_orchestration.git
cd glue-workflow-cdk
#上传Python脚本到Glue的默认S3桶
aws s3 cp dummy.py s3://aws-glue-scripts-<account ID>-<region>/
export GLUE_SCRIPT_S3="s3://aws-glue-scripts-<account ID>-<region>/dummy.py"
cdk init
#部署Glue任务的定义
cdk deploy glue-job-cdk
#部署Glue工作流的定义
cdk deploy glue-workflow-cdk

*左滑查看更多

在 Amazon CloudFormation Stack中我们能看到创建了两个堆栈

  • glue-job-cdk 部署了描述文件中所有的 Amazon Glue ET L任务。由于示例代码仅关注任务之间的编排,每个任务都使用了一个最简单的 Spark 脚本,使用了Glue 2.0的引擎并且分配了5个 DPU 。

  • glue-workflow-cdk 部署了 Amazon Glue 工作流的定义,并且激活了工作流中的每一个触发器。

f1ce6338bd2a1e22009923168c9d4466.png

在 Amazon Glue管理界面上,我们可以看到如下的工作流

7e596671899162cdc5f2cb91c21bfdcf.png

尝试启动工作流,可以看到执行成功。

b17b1a5a6baefbee5fda70400a195d96.png

更新工作流

当开发人员在工作流需要添加一个任务 test-job-4,并且更改任务之间依赖,他只需要在json文件里修改。

102e0281a274395548fef5bddcc7c8b1.png

重新部署 Amazon Glue 任务和 Amazon Glue 工作流的 CDK 堆栈

cp updated_sample_workflow.json sample_workflow.json
cdk deploy glue-job-cdk
cdk deploy glue-workflow-cdk

*左滑查看更多

在 CloudFormation glue-workflow-cdk 堆栈的 Changes 里,我们注意到在只有变化的部分被更新了。

f16cf0aee670b3325d4cf64f6f17b941.png

在工作流界面上可以发现任务 test-job-4 已经被加到工作流里

f2bd7f57b0f73490b7c34c8041051214.png

虽然在我们的示例中只有几个任务的工作流,但是在实践中可以应用到更多更复杂的工作流的更新上。使用 CDK 的部署方式使得开发人员只需要维护比较简单的依赖描述文件,而不需要去反复实现工作流部署的代码。

在使用 CDK 部署工作流的同时,需要注意以下 Amazon CloudFormation 的一些限制

  •  Amazon CloudFormation 单个 Stack 资源上限:由于任务的堆栈里每个工作流、任务、触发器都会对应一个资源,需要注意单个堆栈最多只能有500个资源。

  • Amazon CloudFormation 单个模板长度上限:如果工作流过长(几百个任务以上),可能会使得 CDK 生成的 Amazon CloudFormation 模板超过1MB的长度限制。

使用 Amazon Glue Workflow 编排任务

Apache Airflow 是近几年流行的一个分布式的通用任务编排平台,通过 DAG(Directed acyclic graph 有向无环图)来管理任务流程的任务调度工具,而 DAG 在 Python 代码中定义,设置任务的依赖关系即可实现任务调度。Airflow 记录了已执行任务的状态,报告故障,必要时重试,并允许安排整个管道或其部分以通过回填来执行。

Airflow 对很多亚马逊云科技上的服务都有集成,提供了丰富的 operator,相当于预先定义好的任务模板,比如可以通过 Amazon EC2StartInstanceOperator启动一台 Amazon EC2 机器。下文中我们会尝试使用 Airflow 来部署同样的工作流。

Airflow 在亚马逊云科技上有各种部署形态,可以基于Amazon EKS,Amazon ECS Fargate。本文中我们使用亚马逊云科技托管的Airflow服务,即 MWAA(Amazon Managed Workflows for Apache Airflow)。MWAA 提供了开箱即用的 Airflow 服务,不需要维护机器,可自动扩展,高可用,减少运维的工作,并且提供了和 IAM 的集成。

在这一节里,我们仅创建 Airflow DAG 做 Amazon Glue任务的编排,Amazon Glue 任务的定义我们沿用上一节 CDK 部署的 Amazon Glue 任务。

创建 MWAA 环境

  1. 执行以下创建 MWAA 环境的 Amazon s3 桶。将Python 依赖 requirements.txt 和 DAG 上传到 Amazon s3 里。

    cd ../glue-airflow/
    export MWAA_S3=s3://<new_bucket_name_for_mwaa_dag>
    aws s3 mb $MWAA_S3
    aws s3 cp requirements.txt $MWAA_S3/
    aws s3 cp sample_workflow.json $MWAA_S3/
    aws s3 cp dags/glue_dag.py $MWAA_S3/dags/

    *左滑查看更多

  2. 按照 MWAA Get Started 文档创建 MWAA 环境,注意以下 MWAA 环境使用的是最新 Airflow 2.0以上的环境,在创建 MWAA 环境时,选择 Airflow 2.0.2。

  3. 给 MWAA 的执行角色添加 Amazon Glue 任务相应的权限。

    POLICY_ARN=$(aws iam create-policy --policy-document file://iam_policy_example/glue-run-policy.json --policy-name glue-run-policy --query Policy.Arn)
    aws iam attach-role-policy --role-name Glue-mwaa-env-role --policy-arn $POLICY_ARN

*左滑查看更多

Amazon Glue ETL 任务 DAG 的实现

虽然 Airflow 提供了 Glue Operator,但目前这个 Operator 仅支持创建并执行 Glue 1.0的任务。由于 Glue 2.0的任务类型启动时间更短,并且运行收费更经济,所以我们希望在示例代码中展示调度 Glue 2.0的任务。我们用 PythonOperator 自定义了 Amazon Glue 的 operator,底下实现使用 AwsBaseHook 启动 Amazon Glue 任务,轮询其状态,并且将任务的唯一标识 ID 记录在 Airflow worker 日志中。

def get_glue_operator_args(job_name):
    glue_client = AwsBaseHook(aws_conn_id='aws_default').get_client_type(client_type='glue')
    response = glue_client.start_job_run(JobName=job_name)
    job_id = response['JobRunId']
    print("Job {} ID: {}".format(job_name,job_id))
    while True:
        status = glue_client.get_job_run(JobName=job_name, RunId=job_id)
        state = status['JobRun']['JobRunState']
        if state == 'SUCCEEDED':
            print('Glue job {} run ID {} succeeded'.format(job_name,job_id))
            break
        if state in ['STOPPED', 'FAILED', 'TIMEOUT', 'STOPPING']:
            print('Glue job {} run ID {} is in {} state'.format(job_name,job_id, state))
            raise Exception
        time.sleep(10)

*左滑查看更多

在 MWAA 中执行 

Amazon Glue ETL 任务的 DAG

登录到 Airflow 的 UI 界面上可以看到 sample-workflow-by-airflow 的 DAG。在启动它之前,我们先设置所需的两个 Airflow 变量。

workflow_file_path:设置为工作流 json 文件的 Amazon S3 URI

max_capacity:这是 Amazon Glue 任务所需的资源容量,即 DPU 数量。此处我们设置为5。

e55cd5f81bbb6e119bed6acace103a51.png

回到 DAG 的界面,将 sample_workflow_by_airflow DAG 设置为 active。在 Graph view 里可以看到这个 DAG 结构和 json 描述文件里的任务相对应。启动 DAG 可以看到 DAG 执行成功。

9d5e41e7a6c76d0614f15cc89b5d2dac.png

虽然每个 DAG 中的 Task instance 和 Amazon Glue 的任务一一对应,但是如果要查找 Amazon Glue 任务的执行日志以及监控指标,我们需要能关联每次执行的 Task Instance 和 Amazon Glue 任务的 Run ID。

2a227efcd6da19f7a36287b1bee95746.png

Task instance 的日志里记录了 Amazon Glue 任务的 Run ID。

401b7fe23f2fcfdcdcfb37d8373baf69.png

根据这个 Run ID,可以在 Amazon Glue 的 CloudWatch Log Group 里搜索日志流,就可以找到对应的日志。

bab2fa551397225fa8cb0686adeb840a.png

5ed3d50cdce5673126cc82326138828b.png

Amazon Glue 任务编排工具比较和总结

虽然本文没有具体介绍 Amazon Step Functions 操作,但为了更全面比较流程编工具优缺点,仍将它加到比较表格中。


Glue Workflow

Airflow (MWAA)

Amazon Step Functions    

 成本

无 (Glue Workflow功能本身是免费的)

中(Environment instance按小时收费,Worker按DAG执行时间收费)  

ETL功能

Glue提供基本调度,重试等功能。高级的监控功能可以通过EventBridge和CloudWatch来实现

Airflow 有更丰富ETL相关功能。比如调度,Job SLA,Pool管理,hook等

有基本流程调度功能。ETL操作相关功能没有Glue Workflow和Airflow 丰富

开发难度

低~中等。小规模项目可以在线配置。Glue任务数量较多时候,可以使用CDK或者boto3自动创建job   

高,需要编写python代码生成DAG

中等。需要了解Step Functions状态机语法

运维难度

低,无需关注HA,性能等问题

中,基于亚马逊云科技提供MWAA,可以大幅度降低Airflow的运维工作量。但使用人员仍关注Airflow的性能和资源情况

低,亚马逊云科技无服务器服务

支持大数据引擎

主要支持Glue任务。可以通过python shell调用其他服务

丰富的operator支持

与大部分亚马逊云科技服务能良好集成。包括 Amazon EMR 服务,Glue ETL任务

可视化功能

可视化配置工作流。可以在页面上进行任务调用,工作流重试功能

Web页面提供丰富ETL相关展示,但无法可视化配置DAG。在任务数量多时,展示更友好

可以通过配置代码在控制台编辑工作流

Amazon Glue Workflow,Airflow 和 Step Functions 有各自的设计哲学和适用场景。如果你不知道如何选择,下面是一些建议:

  • Amazon Step Functions 优势在于集成亚马逊云科技服务。如果 ETL  规模很小而且需要集成亚马逊云科技其它服务,如 Amazon Lambda, Amazon EMR 等,Step functions 是最佳选项。

  • 项目规模较小,团队开发能力偏弱,可以先尝试使用Amazon Glue Workflow。

  • 如果项目规模庞大,数据流程复杂度比较高,可以考虑使用 Airflow 作为 Amazon Glue 任务调度工具。

本篇作者

09a453fde332a9d75056d0bfddaf9b57.png

高怿之

亚马逊云科技解决方案架构师

负责跨国企业客户的解决方案咨询,应用架构设计优化,同时致力于亚马逊云科技无服务器类服务的应用和推广。加入亚马逊云科技之前曾在 IBM 存储部门担任软件架构师。

910390c522c5f2cf27a01056042902c5.png

李国建

亚马逊云科技大数据架构师

主要为客户提供数据处理和分析相关的架构设计和技术咨询服务。包括数据分析系统性能优化 ,数据平台架构和规划,实时流处理架构,数据湖架构等。在零售,金融等行业有丰富实践经验。

e9f697e766e843a1e1f5e96168bbcab7.png

扫描上方二维码即刻注册

410429b79abd0d7446fd29d99c3a18d2.gif

29270a2f326c770cbbbc017680036519.gif

听说,点完下面4个按钮

就不会碰到bug了!

8511cbad69871f785838f9cb991bfc64.gif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值