AWS 批量构造库
AWS CDK v1在2023-06-01上达到了支持结束. 此软件包不再更新,用户应该迁移到 AWS CDK v2.
关于如何移徙的更多信息,请参见: 移动到 AWS CDK v2 指南。 。 。 .
这个模块是 AWS 云开发套件 项目.
AWS Batch是AWS中高效运行数十万个计算工作的批量处理工具. 批量可以动态地根据所提交工作的资源需求提供不同类型的计算资源.
AWS 批量简化了对您批量工作量的规划、排期和执行,如一系列计算服务 亚马逊EC2 财务报告和审定财务报表 点资源。 。 。 .
批次通过使用批次任务请求的队列处理来实现此目的. 要成功提交任务执行, 您需要以下资源 :
- 任务定义 - 说吧 将各种工作属性(容器图像,资源要求,env变量.)分组为一个单一定义. 这些定义在工作提交时使用.
- 计算环境 - 说吧 提交批次任务的执行时间
- 任务队列 - 说吧 通过 AWS SDK/CLI 可提交批量任务的队列
详情 AWS 批次 访问 批次的 AWS 文档。 。 。 .
计算环境
AWS Batch的核心是计算环境. 所有批次的工作都是在计算环境中处理的,使用OnDemand/Spot EC2例或Fargate等资源.
单位 管理 模式,AWS将处理提供计算资源以满足需求。 否则,在 联合国 模式中,您需要管理这些资源的提供.
以下是每种可用的计算环境的例子:
declare const vpc: ec2.Vpc;
// default is managed
const awsManagedEnvironment = new batch.ComputeEnvironment(this, 'AWS-Managed-Compute-Env', {
computeResources: {
vpc,
}
});
const customerManagedEnvironment = new batch.ComputeEnvironment(this, 'Customer-Managed-Compute-Env', {
managed: false, // unmanaged environment
});
点计算环境
有可能让 AWS 批量提交当场请求以获取计算资源. 以下是如何做到这一点的例子:
const vpc = new ec2.Vpc(this, 'VPC');
const spotEnvironment = new batch.ComputeEnvironment(this, 'MySpotEnvironment', {
computeResources: {
type: batch.ComputeResourceType.SPOT,
bidPercentage: 75, // Bids for resources at 75% of the on-demand price
vpc,
},
});
远端计算环境
有可能让 AWS Batch 提交任务在 Fargate 计算资源上运行 。 以下是如何做到这一点的例子:
const vpc = new ec2.Vpc(this, 'VPC');
const fargateSpotEnvironment = new batch.ComputeEnvironment(this, 'MyFargateEnvironment', {
computeResources: {
type: batch.ComputeResourceType.FARGATE_SPOT,
vpc,
},
});
理解逐步分配战略
AWS 批次使用一个 分配战略 确定计算资源将有效处理收到的工作请求。 默认, 最佳结果 将根据vCPU的要求选择可用的计算实例。 如果不存在,则工作将等待资源到位。 然而,通过这一策略,您可能会有工作在排队中不必要的等待,尽管有更强大的实例可用。 下面是这种情况的一个例子:
Compute Environment:
1. m5.xlarge => 4 vCPU
2. m5.2xlarge => 8 vCPU
Job Queue:
---------
| A | B |
---------
Job Requirements:
A => 4 vCPU - ALLOCATED TO m5.xlarge
B => 2 vCPU - WAITING
在这种情况下,批量将分配 任务A 以计算资源 # 1 ,因为它是符合 vCPU 要求的成本效益最高的资源。 不过,有了这个 BEST_FIT 战略, 任务B 将不分配给我们其他可用的计算资源,尽管它足够强大,足以处理它。 相反,它会等到第一个任务完成 或等待一个类似的 m5.xlarge 资源.
替代办法是使用 BEST_FIT_PROGRESSIVE (c) 制定战略,使剩余工作能够在更大的容器中处理,而不论VCPU的要求和费用如何.
启动模板支持
简单定义您的启动模板 :
// This example is only available in TypeScript
const myLaunchTemplate = new ec2.CfnLaunchTemplate(this, 'LaunchTemplate', {
launchTemplateName: 'extra-storage-template',
launchTemplateData: {
blockDeviceMappings: [
{
deviceName: '/dev/xvdcz',
ebs: {
encrypted: true,
volumeSize: 100,
volumeType: 'gp2',
},
},
],
},
});
并使用它:
declare const vpc: ec2.Vpc;
declare const myLaunchTemplate: ec2.CfnLaunchTemplate;
const myComputeEnv = new batch.ComputeEnvironment(this, 'ComputeEnv', {
computeResources: {
launchTemplate: {
launchTemplateName: myLaunchTemplate.launchTemplateName as string, //or simply use an existing template name
},
vpc,
},
computeEnvironmentName: 'MyStorageCapableComputeEnvironment',
});
导入已有的计算环境
要导入已有的批量计算环境, 请打电话 ComputeEnvironment.fromComputeEnvironmentArn()。 。 。 .
以下是一个例子:
const computeEnv = batch.ComputeEnvironment.fromComputeEnvironmentArn(this, 'imported-compute-env', 'arn:aws:batch:us-east-1:555555555555:compute-environment/My-Compute-Env');
更改计算资源的基准AMI
有时,您需要偏离默认处理 AMI .
ECS 优化了 Amazon Linux 2 的例子 :
declare const vpc: ec2.Vpc;
const myComputeEnv = new batch.ComputeEnvironment(this, 'ComputeEnv', {
computeResources: {
image: new ecs.EcsOptimizedAmi({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
}),
vpc,
}
});
自定义的 AMI 示例 :
declare const vpc: ec2.Vpc;
const myComputeEnv = new batch.ComputeEnvironment(this, 'ComputeEnv', {
computeResources: {
image: ec2.MachineImage.genericLinux({
"[aws-region]": "[ami-ID]",
}),
vpc,
}
});
任务队列
工作总是被提交到特定的排队。 这意味着您必须先创建队列才能开始提交任务 。 每个队列被映射到至少一个(不超过三个)计算环境. 当任务被安排执行时,AWS Batch会根据每个环境中的平分优先和可用能力选择计算环境.
declare const computeEnvironment: batch.ComputeEnvironment;
const jobQueue = new batch.JobQueue(this, 'JobQueue', {
computeEnvironments: [
{
// Defines a collection of compute resources to handle assigned batch jobs
computeEnvironment,
// Order determines the allocation order for jobs (i.e. Lower means higher preference for job assignment)
order: 1,
},
],
});
以先入为主的队列示例
有时,您可能拥有比其他人更重要的工作,在提交工作时,应优先于现有的工作。 为此,您可以通过给每个队列分配自己的优先级来创建基于优先级的执行策略:
declare const sharedComputeEnvs: batch.ComputeEnvironment;
const highPrioQueue = new batch.JobQueue(this, 'JobQueue', {
computeEnvironments: [{
computeEnvironment: sharedComputeEnvs,
order: 1,
}],
priority: 2,
});
const lowPrioQueue = new batch.JobQueue(this, 'JobQueue', {
computeEnvironments: [{
computeEnvironment: sharedComputeEnvs,
order: 1,
}],
priority: 1,
});
通过在两个工作队列之间确保使用相同的计算环境,我们将优先考虑 highPrioQueue 用于为现有计算环境分配工作.
导入已有的任务队列
要导入已有的批量任务队列, 请拨 JobQueue.fromJobQueueArn()。 。 。 .
以下是一个例子:
const jobQueue = batch.JobQueue.fromJobQueueArn(this, 'imported-job-queue', 'arn:aws:batch:us-east-1:555555555555:job-queue/High-Prio-Queue');
任务定义
一个批次任务定义帮助AWS批次理解如何在批次任务范围内运行您的应用程序的重要细节. 这涉及到诸如资源需求、运行何种容器、应如何准备计算环境等关键信息,以及更多的信息。 以下是如何创建工作定义的简单例子:
import * as ecr from '@aws-cdk/aws-ecr';
const repo = ecr.Repository.fromRepositoryName(this, 'batch-job-repo', 'todo-list');
new batch.JobDefinition(this, 'batch-job-def-from-ecr', {
container: {
image: new ecs.EcrImage(repo, 'latest'),
},
});
使用本地的 Docker 项目
下面是您如何从本地 Docker 应用程序创建批量任务定义的例子 .
new batch.JobDefinition(this, 'batch-job-def-from-local', {
container: {
// todo-list is a directory containing a Dockerfile to build the application
image: ecs.ContainerImage.fromAsset('../todo-list'),
},
});
提供自定义日志配置
您可以为容器提供自定义日志驱动程序及其配置 .
import * as ssm from '@aws-cdk/aws-ssm';
new batch.JobDefinition(this, 'job-def', {
container: {
image: ecs.EcrImage.fromRegistry('docker/whalesay'),
logConfiguration: {
logDriver: batch.LogDriver.AWSLOGS,
options: { 'awslogs-region': 'us-east-1' },
secretOptions: [
batch.ExposedSecret.fromParametersStore('xyz', ssm.StringParameter.fromStringParameterName(this, 'parameter', 'xyz')),
],
},
},
});
导入已有的工作定义
从ARN
要从 ARN 中导入现有的批量工作定义, 请拨打 JobDefinition.fromJobDefinitionArn()。 。 。 .
以下是一个例子:
const job = batch.JobDefinition.fromJobDefinitionArn(this, 'imported-job-definition', 'arn:aws:batch:us-east-1:555555555555:job-definition/my-job-definition');
从名
要从名称中导入现有的批量任务定义, 请打电话 JobDefinition.fromJobDefinitionName()。 。 。 .
如果未修订而指定名称,则使用最新的活性修订.
以下是一个例子:
// Without revision
const job1 = batch.JobDefinition.fromJobDefinitionName(this, 'imported-job-definition', 'my-job-definition');
// With revision
const job2 = batch.JobDefinition.fromJobDefinitionName(this, 'imported-job-definition', 'my-job-definition:3');