使用 AWS Batch 和 AWS Step Functions 将 AWS Batch 与 Step Functions 结合使用以创建视频处理工作流

基于云的视频托管服务会定期对上传到云端的视频进行视频转码和特征提取。视频处理管道往往需要一套复杂的工作流来管理多个并行计算作业并处理异常。

在本教程中,您将创建一套 AWS Step Functions 工作流,用于模拟上传到云端的视频的处理流程。该工作流将通过把作业提交到 Amazon Batch 服务上的多优先级队列来处理视频。

Step Functions 工作流将用于指定提交到 AWS Batch 的依赖项和序列作业。在 AWS Batch 中,用户可以定义计算环境、队列和队列优先级。Step Functions 工作流可用于指定如何在工作流中处理异常。

注意:该工作流不会执行任何实际的处理操作。在本教程中,您可以在 AWS 免费套餐的范围内试用 AWS Step Functions 和 AWS Batch。请务必在配置计算环境时遵循教程建议,并在完成教程后删除所有资源,以免产生额外费用。

AWS Step Functions workflow
关于本教程
时间 10 分钟
费用 免费
使用场景 无服务器
产品 AWS Batch、AWS Step Functions
级别 100
上次更新时间 2019 年 10 月 10 日

步骤 1:设置

1.1 打开浏览器并前往 AWS Batch 控制台。如果您已经拥有 AWS 账户,请登录该控制台。否则,请创建一个新 AWS 账户以开始学习。

已经拥有账户? 登录您的账户

1.2 我们将使用标准 Batch 控制台。如果您看到显示 Get started(开始使用)的页面,请点击 Get started(开始使用)。否则请跳到步骤 2。

1.3 点击 Skip wizard(跳过向导)。在本教程中,我们将使用标准 Batch 控制台。

现在,您将看到 AWS Batch 控制台。

步骤 2:设置 Batch 作业

下一步是设置 AWS Batch 计算环境。该计算环境会指定可用于运行批处理作业的最小、理想和最大 CPU 数量。 

2.1 在左侧面板中点击 Compute environments(计算环境)。您将保留大多数元素的默认设置,仅更改少数条目。

2.2 点击 Create environment(创建环境)。

2.3 在 Compute environment name(计算环境名称)文本框中输入 StepsBatchTutorial_ComputeEnv

为 Service role(服务角色)选择 Create new role(创建新角色)。

2.4 在计算资源方面,将 Minimum vCPUs(最小 vCPU 数量)设置为 0,将 Desired vCPUs(理想 vCPU 数量)设置为 2,并将 Maximum vCPUs(最大 vCPU 数量)设置为 4。

您可以限制 CPU 资源以降低教程所需的费用。将 Minimum vCPUs(最小 vCPU 数量)设置为 0,可以确保在没有活动作业提交到队列时不会浪费 CPU 时间。将 vCPUS 数量设置为 0 的缺点是:提交作业后,如果没有活动的 vCPU,则在分配和启动 vCPU 时会出现冷启动延迟。

2.5 点击 Create(创建)。现在,您将看到创建的环境。计算环境创建完成后,预配模型为 EC2,Status(状态)为 VALID(有效),State(状态)为 ENABLED(已启用)。此过程可能需要几分钟时间。点击刷新按钮可刷新状态。

步骤 3:设置 AWS Batch 队列

现在,您将创建两个具有不同优先级的 AWS Batch 队列。

3.1 在左侧面板中选择 Job queues(作业队列)。

3.2 点击 Create queue(创建队列)。

3.3 在 Queue name(队列名称)文本框中输入 StepsBatchTutorial_HighPriorityQueue

在 Priority(优先级)文本框中输入 10。具有更高整数值的作业队列将优先获得计算资源。

从下拉菜单中选择计算环境 StepsBatchTutorial_ComputeEnv

点击 Create Job Queue(创建作业队列)。

3.4 您的队列现已创建。您可以创建优先级较低的第二个队列。点击 Create queue(创建队列)。

3.5 在 Queue name(队列名称)文本框中输入 StepsBatchTutorial_LowPriorityQueue

在 Priority(优先级)文本框中输入 1。

从下拉菜单中选择计算环境 StepsBatchTutorial_ComputeEnv

点击 Create Job Queue(创建作业队列)。

现在,您已创建两个队列。

步骤 4:设置作业定义

现在,您将创建一系列虚拟作业,系统可将其作为批处理作业的一部分执行。

4.1 在左侧面板中点击 Job definitions(作业定义)。

4.2 点击 Create(创建)。

注意:为了完成本教程,我们将使用一个 Amazon Linux 容器来帮助说明各个工作流步骤。该容器不会执行任何实际工作。为目标使用场景创建批处理环境时,您需要提供一个能够执行所需处理操作的容器。有关更多详细信息,请参阅 AWS Batch 用户指南中的创建作业定义

4.3 在 Job definition name(作业定义名称)文本框中输入 StepsBatchTutorial_TranscodeVideo

点击 Create Job Definition(创建作业定义)。

注意:为了完成本教程,我们将使用一个 Amazon Linux 容器来帮助说明各个工作流步骤,而不会执行任何处理操作。用户需要提供自己的容器来运行批处理作业。

4.4 在 Container image(容器镜像)文本框中输入 137112412989.dkr.ecr.us-east-2.amazonaws.com/amazonlinux:latest

将 Command(命令)设置为 echo Performing Video Transcoding Job

将 vCPUs(vCPU 数量)设置为 2。

将 Memory (MiB)(内存 (MiB))设置为 1024。

4.5 点击 Create Job Definition(创建作业定义)。

4.6 重复步骤 4.1 和 4.2,再创建两个作业。

对于第二个作业,将 Job definition name(作业定义名称)设置为 StepsBatchTutorial_FindFeatures,并将 Command(命令)设置为 echo Performing Video Feature Extraction

对于第三个作业,将 Job definition name(作业定义名称)设置为 StepsBatchTutorial_ExtractMetadata,并将 Command(命令)设置为 echo Extracting Metadata from Video

步骤 5:使用状态机创建工作流

现在,您将创建一个状态机来控制工作流和调用 AWS Batch。工作流将一个流程描述为一系列可以不断重复执行的离散任务。您将在 AWS Step Functions 中设计工作流。AWS Step Function 会使用状态机来创建工作流。状态机使用 Amazon States Language (ASL) 语言以 JSON 格式进行编码。

5.1 打开 AWS Step Functions 控制台以创建状态机。选择 Author with code snippets(使用代码段编写)。在 Name(名称)文本框中,将您的状态机命名为 StepsBatchTutorial_VideoWorkflow

5.2 将 State machine definition(状态机定义)窗口中的内容替换为以下基于 Amazon States Language (ASL) 的状态机定义。Amazon States Language 是基于 JSON 的结构化语言,用于定义状态机。

此状态机表示使用批处理执行视频处理的工作流。大多数步骤都是执行 AWS Batch 作业的 Task 状态。Task 状态还可用于调用其他 AWS 服务,例如调用 Lambda 进行无服务器计算,或者调用 SNS 发送扇出到其他服务的消息。

{
    "StartAt": "Extract Metadata",
    "States": {
        "Extract Metadata": {
            "Type": "Task",
            "Resource": "arn:aws:states:::batch:submitJob.sync",
            "Parameters": {
                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_ExtractMetadata:1",
                "JobName": "SplitVideo",
                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_HighPriorityQueue"
            },
            "Next": "Process Video"
        },
        "Process Video": {
            "Type": "Parallel",
            "End": true,
            "Branches": [
                {
                    "StartAt": "Extract Features",
                    "States": {
                        "Extract Features": {
                            "Type": "Task",
                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                            "Parameters": {
                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_ExtractFeatures:1",
                                "JobName": "ExtractFeatures",
                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_LowPriorityQueue"
                            },
                            "End": true
                        }
                    }
                },
                {
                    "StartAt": "Transcode Video",
                    "States": {
                        "Transcode Video": {
                            "Type": "Parallel",
                            "End": true,
                            "Branches": [
                                {
                                    "StartAt": "Transcode_4k-1",
                                    "States": {
                                        "Transcode_4k-1": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_4k-1",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_HighPriorityQueue"
                                            },
                                            "Next": "Transcode_4k-2"
                                        },
                                        "Transcode_4k-2": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_4k-2",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_LowPriorityQueue"
                                            },
                                            "End": true
                                        }
                                    }
                                },
                                {
                                    "StartAt": "Transcode_1080p-1",
                                    "States": {
                                        "Transcode_1080p-1": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_1080p-1",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_HighPriorityQueue"
                                            },
                                            "Next": "Transcode_1080p-2"
                                        },
                                        "Transcode_1080p-2": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_1080p-2",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_LowPriorityQueue"
                                            },
                                            "End": true
                                        }
                                    }
                                },
                                {
                                    "StartAt": "Transcode_720p-1",
                                    "States": {
                                        "Transcode_720p-1": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_720p-1",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_HighPriorityQueue"
                                            },
                                            "Next": "Transcode_720p-2"
                                        },
                                        "Transcode_720p-2": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_720p-2",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_LowPriorityQueue"
                                            },
                                            "End": true
                                        }
                                    }
                                },
                                {
                                    "StartAt": "Transcode_480p-1",
                                    "States": {
                                        "Transcode_480p-1": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_480p-1",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_HighPriorityQueue"
                                            },
                                            "Next": "Transcode_480p-2"
                                        },
                                        "Transcode_480p-2": {
                                            "Type": "Task",
                                            "Resource": "arn:aws:states:::batch:submitJob.sync",
                                            "Parameters": {
                                                "JobDefinition": "arn:aws:batch:REGION:112233445566:job-definition/StepsBatchTutorial_TranscodeVideo:1",
                                                "JobName": "Transcode_480p-2",
                                                "JobQueue": "arn:aws:batch:REGION:112233445566:job-queue/StepsBatchTutorial_LowPriorityQueue"
                                            },
                                            "End": true
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

5.3 点击刷新按钮,让 Step Functions 将 ASL 状态机定义转换为可视化工作流。您可以通过查看可视化工作流来轻松验证流程描述是否正确。

这个示例使用了 Parallel 和 Task 状态。ASL 语言指定了一些可用的不同状态类型。

5.4 对于每个 Batch 作业的 Task 状态,都需要更新 ARN 以匹配您的区域和账户。Batch 作业的 Task 状态包含三个字段。第一个字段是对将要执行的作业名称的引用。第二个字段是将要分配给作业的名称。第三个字段是为其分配作业的队列。

对于每个 Batch Task,进行以下替换:

将虚拟 REGION(区域)替换为您的工作所在区域,例如 US-EAST-1。

将虚拟账号 112233445566 替换为您的 AWS 账号。

使用文本编辑器或 VSCode 等 IDE 进行搜索和替换,速度会更快。请确保替换 ARN 中的所有 20 个账户引用。

5.5 点击 Next(下一步)。

5.6 接下来,您将在工作流中添加 IAM 角色。选择 Create an IAM role for me(为我创建 IAM 角色),并将该角色命名为 StepsBatchTutorial_Role。Step Functions 会分析工作流并生成 IAM 策略,其中包括工作流使用的资源。

点击 Create state machine(创建状态机)。您应当会看到一个绿色横幅,表明状态机创建成功。

5.7 点击 Create state machine(创建状态机)

步骤 6:执行工作流

下一步是执行您已构建的 Step Functions 工作流。您将手动触发开始执行。可以指定以 JSON 格式向 Step Functions 提供输入数据。Step Functions 还可以由 Lambda 函数或 CloudWatch 事件触发。

6.1 点击 Start execution(开始执行)。

6.2 在 New execution(新执行)窗口中,您无需输入数据,因此可以保持 JSON 不变。点击 Start execution(开始执行)。

6.3 您将看到工作流开始执行。作业被发送至 Batch。由于工作流是同步执行的,因此工作流会等到每个 Batch 作业都完成后再执行下一步。

6.4 在页面上比较靠下的位置,您可以找到可视化工作流。点击 Transcode_1080p-1 步骤,即可在页面右侧查看步骤的详细信息。

6.5 在页面底部,查看执行事件历史记录。点击 ID 6。在该事件中,提交的第一个批处理作业已完成任务。

Step 函数将暂停在 Extract Metadata(提取元数据)状态,直到批处理任务完成。

6.6 您可以查看有关 Batch 作业执行的详细信息。前往 Batch 服务,然后在左侧导航栏中选择 Dashboard(控制面板)。您将在 Job queues(作业队列)下方看到作业的状态。点击刷新按钮,查看队列中各个作业的进度。

在 Step Functions 控制台上,多次重复运行状态机,并在 Step Functions 控制台和 Batch 控制台之间来回切换,观察批处理作业和队列的性能。

若要查看已执行批处理作业的详细信息,请点击 SUCCEEDED(已完成)下的某个作业队列编号。

6.7 点击列表中的一个 Job ID(作业 ID)以查看更多详细信息。

6.8 您可以查看作业的详细信息,包括开始时间、完成时间、作业队列和使用的容器。

向下滚动到 Attempts(尝试次数)部分,然后点击 View logs(查看日志)。此操作将打开 CloudWatch Logs 控制台。

6.9 在 CloudWatch Logs 中,您可以查看作业执行历史记录。请注意日志中如何捕获您为作业输入的 echo 语句。

6.10(可选)现在,您有机会使用状态机进行更多尝试。返回 Step Functions 控制台并编辑状态机代码。

尝试更改队列优先级并重新执行状态机。

6.11(可选)对于第二个作业,将 Transcode_4k-1 JobDefinition 替换为 arn:aws:batch:us-west-2:134029540168:job-definition/StepsBatchTutorial_TranscodeVideo_DOES_NOT_EXIST:1

重新执行状态机,并注意以下情况:如果一个并行批处理作业失败,则系统将取消所有其他并行作业。一旦失败,所有批处理作业都会被移出队列。

在状态机中引入故障处理。可以使用 Task 状态的 Retry 字段来多次重试作业。可以引入 Catch 语句来执行错误处理。有关更多信息,请参阅 Amazon States Language 错误处理

步骤 7:终止资源

在此步骤中,您将终止 AWS Step Functions 和 AWS Batch 相关资源。重要说明:终止当前未使用的资源可降低成本,这是一种最佳做法。如果没有终止资源,系统可能会收取费用。

7.1 首先,您将删除您的 Step 函数。在 AWS 管理控制台菜单中点击 Services(服务),然后选择 Step Functions

在 State machines(状态机)窗口中,选择状态机 StepsBatchTutorial_VideoWorkflow,然后点击 Delete(删除)。在对话框中选择 Delete state machine(删除状态机),以确认删除操作。一旦 Step Functions 确认任何进程中的执行操作已完成,您的状态机就会在一两分钟内被删除。

7.2 接下来,您将删除您的 Batch 队列和计算环境。在 AWS 管理控制台菜单中点击 Services(服务),然后选择 Batch。在左侧菜单中选择 Job definitions(作业定义)。

对于每个作业定义,点击作业定义名称,选择 Revision 1 旁边的单选框,然后依次选择 Actions(操作)和 Deregister(注销)。您的作业将被注销。对您的每个作业执行这一操作。

7.3 接下来,您将删除您的作业队列。在左侧菜单中点击 Job queues(作业队列)。

选择 StepsBatchTutorial_HighPriority 队列旁边的单选框。选择 Disable(禁用)。禁用队列后,重新选择队列,然后点击 Delete(删除)。

StepsBatchTutorial_LowPriority 队列重复删除操作。完成队列删除可能需要一分钟。

7.4 接下来,您将删除您的计算环境。在左侧菜单中点击 Compute environments(计算环境)。

选择 StepsBatchTutorial_Compute 计算环境队列旁边的单选框。选择 Disable(禁用)。禁用计算环境后,重新选择计算环境,然后点击 Delete(删除)。待作业队列的删除后,您才能删除计算环境。

7.5 最后,您将删除您的 IAM 角色。在 AWS 管理控制台菜单中点击 Services(服务),然后选择 IAM

在左侧菜单中选择 Roles(角色)。输入 StepsBatchTutorial 并选择您为本教程创建的 IAM 角色,然后点击 Delete role(删除角色)。在对话框中点击 Yes, delete(是的,删除)以确认删除操作。

恭喜您

现在,您已使用 AWS Step Functions 和 AWS Batch 编排了一个试验视频转码工作流。如果您需要编排复杂的批处理作业以及处理错误和作业失败,那么 Step Functions 非常适合您。

此页内容对您是否有帮助?

推荐的后续步骤

进一步了解错误处理

您现已学会如何创建与 Batch 集成的状态机,可以继续学习下一个教程,其中您将了解如何处理无服务器应用程序中的错误。Step Functions 能让您轻松处理工作流运行时错误。

阅读文档

通过阅读 AWS Step Functions 开发人员指南,了解 AWS Step Functions 的功能和能力。 

探索 AWS Step Functions

如果您想要进一步了解 AWS Step Functions,请访问 AWS Step Functions 产品页面以浏览相关文档、视频、博客等。