繁体   English   中英

AWS Batch 作业执行结果在步骤 Function

[英]AWS Batch Job Execution Results in Step Function

我是 AWS Step Functions 和 AWS Batch 的新手。 我正在尝试将 AWS Batch Job 与步骤 Function 集成。AWS Batch Job 执行简单的 python 脚本,其中 output 字符串值(高级简化要求)。 我需要将 python 脚本 output 提供给步骤 function 的下一个 state。我应该如何完成此操作。 AWS Batch 作业 output 不包含 python 脚本的结果。 相反,它包含所有与输入值相关的容器信息。

示例:AWS 批处理作业执行 python 脚本,其中 output “Hello World”。 我需要“Hello World”可用于步骤 function 的下一个 state 以执行与其关联的 lambda。

我能够做到,下面是我的 state 机器,我采用了运行批处理作业管理批处理作业(AWS Batch、Amazon SNS)的示例项目,并将其修改为两个 lambda 表达式以传递输入/输出。

{
  "Comment": "An example of the Amazon States Language for notification on an AWS Batch job completion",
  "StartAt": "Submit Batch Job",
  "TimeoutSeconds": 3600,
  "States": {
    "Submit Batch Job": {
      "Type": "Task",
      "Resource": "arn:aws:states:::batch:submitJob.sync",
      "Parameters": {
        "JobName": "BatchJobNotification",
        "JobQueue": "arn:aws:batch:us-east-1:1234567890:job-queue/BatchJobQueue-737ed10e7ca3bfd",
        "JobDefinition": "arn:aws:batch:us-east-1:1234567890:job-definition/BatchJobDefinition-89c42b1f452ac67:1"
      },
      "Next": "Notify Success",
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "Notify Failure"
        }
      ]
    },
    "Notify Success": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:1234567890:function:readcloudwatchlogs",
      "Parameters": {
        "LogStreamName.$": "$.Container.LogStreamName"
      },
      "ResultPath": "$.lambdaOutput",
      "Next": "ConsumeLogs"
    },
    "ConsumeLogs": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:1234567890:function:consumelogs",
      "Parameters": {
        "randomstring.$": "$.lambdaOutput.logs"
      },
      "End": true
    },
    "Notify Failure": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "Message": "Batch job submitted through Step Functions failed",
        "TopicArn": "arn:aws:sns:us-east-1:1234567890:StepFunctionsSample-BatchJobManagement17968f39-e227-47ab-9a75-08a7dcc10c4c-SNSTopic-1GR29R8TUHQY8"
      },
      "End": true
    }
  }
}

读取日志的关键在Submit Batch Job output 中,其中包含LogStreamName ,我将其传递给名为function:readcloudwatchlogs的 lambda 并读取日志,然后最终将读取日志传递给名为function:consumelogs的下一个 function 您可以在附带的屏幕截图中看到consumelogs function 打印日志。


{
  "Attempts": [
    {
      "Container": {
        "ContainerInstanceArn": "arn:aws:ecs:us-east-1:1234567890:container-instance/BatchComputeEnvironment-4a1593ce223b3cf_Batch_7557555f-5606-31a9-86b9-83321eb3e413/6d11fdbfc9eb4f40b0d6b85c396bb243",
        "ExitCode": 0,
        "LogStreamName": "BatchJobDefinition-89c42b1f452ac67/default/2ad955bf59a8418893f53182f0d87b4b",
        "NetworkInterfaces": [],
        "TaskArn": "arn:aws:ecs:us-east-1:1234567890:task/BatchComputeEnvironment-4a1593ce223b3cf_Batch_7557555f-5606-31a9-86b9-83321eb3e413/2ad955bf59a8418893f53182f0d87b4b"
      },
      "StartedAt": 1611329367577,
      "StatusReason": "Essential container in task exited",
      "StoppedAt": 1611329367748
    }
  ],
  "Container": {
    "Command": [
      "echo",
      "Hello world"
    ],
    "ContainerInstanceArn": "arn:aws:ecs:us-east-1:1234567890:container-instance/BatchComputeEnvironment-4a1593ce223b3cf_Batch_7557555f-5606-31a9-86b9-83321eb3e413/6d11fdbfc9eb4f40b0d6b85c396bb243",
    "Environment": [
      {
        "Name": "MANAGED_BY_AWS",
        "Value": "STARTED_BY_STEP_FUNCTIONS"
      }
    ],
    "ExitCode": 0,
    "Image": "137112412989.dkr.ecr.us-east-1.amazonaws.com/amazonlinux:latest",
    "LogStreamName": "BatchJobDefinition-89c42b1f452ac67/default/2ad955bf59a8418893f53182f0d87b4b",
    "TaskArn": "arn:aws:ecs:us-east-1:1234567890:task/BatchComputeEnvironment-4a1593ce223b3cf_Batch_7557555f-5606-31a9-86b9-83321eb3e413/2ad955bf59a8418893f53182f0d87b4b",
..
  },
..
  "Tags": {
    "resourceArn": "arn:aws:batch:us-east-1:1234567890:job/d36ba07a-54f9-4acf-a4b8-3e5413ea5ffc"
  }
}

  • 读取日志 Lambda 代码:
import boto3

client = boto3.client('logs')

def lambda_handler(event, context):
    print(event)
    response = client.get_log_events(
        logGroupName='/aws/batch/job',
        logStreamName=event.get('LogStreamName')
    )
    log = {'logs': response['events'][0]['message']}
    return log
  • 消费日志 Lambda 代码
import json

print('Loading function')


def lambda_handler(event, context):
    print(event)

在此处输入图像描述

在此处输入图像描述

您可以将步骤 function 执行 ID ($$.Execution.ID) 传递给批处理,然后您的批处理可以使用执行 ID 和主键(或其他字段)将其响应写入 DynamoDB。 然后,您将需要一个后续步骤来直接从 DynamoDB 读取并捕获流程响应。

我一直在寻找一种无需后续步骤即可执行此操作的方法,但到目前为止还没有成功。

我是 AWS Step Functions 和 AWS Batch 的新手。 我正在尝试将 AWS Batch Job 与 Step Function 集成。 AWS Batch Job 执行简单的 python 脚本,其中 output 字符串值(高级简化要求)。 我需要 python 脚本 output 可用于步骤 ZC1C425268E68385D1ABZA50744 的下一个 state。 我应该如何做到这一点。 AWS Batch Job output 不包含 python 脚本的结果。 相反,它包含所有带有输入值的容器相关信息。

示例:AWS Batch Job 执行 python 脚本 output “Hello World”。 我需要“Hello World”可用于步骤 function 的下一个 state 以执行与其关联的 lambda。

虽然您不能使用waitForTaskToken执行submitJob ,但您仍然可以通过在参数中传递任务令牌并在command重写中使用Ref::TaskToken引用它来使用回调模式:

...
   "Submit Batch Job": {
      "Type": "Task",
      "Resource": "arn:aws:states:::batch:submitJob.sync",
      "Parameters": {
         "TaskToken.$": "$$.Task.Token"
      },
      "ContainerOverrides": {
         "command": ["python3", 
                     "my_script.py", 
                     "Ref::TaskToken"]
      }
...

然后,当您的脚本完成处理后,您只需调用StepFunctions.SendTaskSuccessStepFunctions.SendTaskFailure

import boto3

client = boto3.client('stepfunctions')

def main()
    args = sys.argv[1:]
    client.send_task_success(taskToken=args[0], output='Hello World')

这将告诉 StepFunctions 您的工作已完成,output 应该是“Hello World”。 如果您的批处理作业完成恢复 state 机器所需的工作,但之后需要做一些清理工作,则此模式也很有用。 您可以使用结果发送任务成功,并且 state 机器可以在批处理作业执行清理工作时恢复。

感谢@samtoddler 的回答。

我们用了一段时间。

但是,最近我的朋友@liorzimmerman 找到了更好的解决方案。

使用stepfunctions send-task-success

从 state 机器调用作业时,您需要发送task-token

  "States": {
"XXX_state": {
  "Type": "Task",
  "Resource": "arn:aws:states:::batch:submitJob.sync",
  "Parameters": {
    "JobDefinition": "arn:aws:batch:us-east-1:XXX:job-definition/task_XXX:4",
    "JobQueue": "arn:aws:batch:us-east-1:XXX:job-queue/XXX-queue",
    "JobName": "XXX",
    "Parameters": {
      "TASK_TOKEN.$": "$$.Task.Token",
    }
  },
  "ResultPath": "$.payload",
  "End": true
}

接下来,在job运行的docker里面,结果发送:

aws stepfunctions send-task-success --task-token $TASK_TOKEN --task-output $OUTPUT_JSON

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM