5

场景:必须处理一堆小尺寸(平均每个 50 字节)的记录(比如 10k,也许更多)。处理必须并行或以任何其他方式进行以提高性能(请记住,我们有很多记录要处理)。此外,处理本身是一项非常简单的任务(这是使用 AWS Lambda 的原因之一)。尽管它很简单,但某些处理可能在其他处理之前/之后结束,因此这是这些记录彼此独立并且处理顺序无关紧要的另一个原因。

到目前为止,Step Functions 看起来像是要走的路。

使用 Step Functions,我们可以得到下图:

在此处输入图像描述

我可以将 RecordsRetrieval 定义为一项任务。之后,这些记录将由任务 ProcessRecords-Task-1、ProcessRecords-Task-2 和 ProcessRecords-Task-3 并行处理。从表面上看,一切都很好,花花公子,对吧?错误的!

第一个问题:动态缩放如果我想动态缩放这些任务(比如说... 10、100、5k 或 10k),考虑到要处理的记录数量,我将不得不动态构建 json 以实现这一点(不是一个非常优雅的解决方案,但它可能会起作用)。我非常有信心任务的数量是有限的,所以我不能依赖它。如果扩展繁重的工作由基础设施而不是我来处理,那就更好了。

无论哪种方式,对于一组定义明确的并行任务,例如:GetAddress、GetPhoneNumber、GetWhatever... 都很棒!奇迹般有效!

第二个问题:Payload Dispatch 在 RecordsRetrieval 任务之后,我需要单独处理这些记录中的每一个。使用 Step Functions,我没有看到任何方法可以做到这一点。一旦 RecordsRetrieval 任务传递了它的有效负载(在这种情况下是那些记录),所有并行任务将处理相同的有效负载。

同样,就像我在第一个问题中所说的那样,对于一组定义明确的并行任务,这将是一个完美的选择。

结论 我认为,AWS Step Functions 可能不是我的场景的解决方案。这是我对此知识的总结,所以如果我确实遗漏了什么,请随时发表评论。

出于多种原因(可扩展性、无服务器、简单性等),我正在研究微服务方法。

我知道可以检索这些记录并一个接一个地发送到另一个 lambda,但同样,这不是一个非常优雅的解决方案。

我也知道这是一个批处理作业,AWS 有批处理服务。我想要做的是保持微服务方法而不依赖于 AWS Batch/EC2。

你对此有什么想法?随意发表评论。任何建议将不胜感激。

4

4 回答 4

3

根据您的意见,根据我的说法,以下解决方案可以符合您的标准。您可以将 AWS lambda 或 AWS batch 用于以下解决方案。

var BATCH_RECORD_SIZE = 100;
var totalRecords = getTotalCountOfRecords();
var noOfBatchInvocation = getTotalCountOfRecords() % BATCH_RECORD_SIZE == 0 ? getTotalCountOfRecords() / BATCH_RECORD_SIZE : getTotalCountOfRecords() /BATCH_RECORD_SIZE + 1;
var start = 0;
for( 1 to noOfBatchInvocation ) {
    // invoke lambda / submit job
    invokeLambda(start, BATCH_RECORD_SIZE);
    // OR
    submitJobWith(start, BATCH_RECORD_SIZE);
    // increment start
    start += BATCH_RECORD_SIZE;
}
  • 定义 lambda 哪个任务将只是获取上面的记录数。这个 lambda 可以在 s3 事件或预定事件上触发,也可以按照您的方式触发。在这里,我们可以定义每个 lambda 调用/批处理作业处理的记录数。此 lambda 将调用/提交批处理作业次数 =(总记录)/(每个作业的记录数/lambda 调用)。
  • 如果您更喜欢 lambda,则定义 lambda,使其接受两个参数 start 和 limit 作为输入。这些参数将决定从哪里开始读取要处理的文件以及在哪里停止。这个 lambda 还将知道从哪里读取记录。
  • 如果您更喜欢批处理,则使用与上述相同的逻辑定义作业定义。

您可以使用 AWS lambda,因为您的记录处理不是计算/内存密集型的。但如果是,那么我会建议使用 AWS 批处理进行此处理。

于 2018-02-13T09:43:49.577 回答
2

AWS Step Function 现在支持使用 Map 生成动态并行任务:https ://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-map-state.html 。

输入在数组中提供,并在完成后输出一个数组。您需要定义 ItemPath(即 InputPath 中数组的位置)。请参阅 ItemPath:https ://docs.aws.amazon.com/step-functions/latest/dg/input-output-itemspath.html 。
这解决了你的两个问题。

第一个问题:将您的 ProcessRecords-Task 定义为 Map。当然,问题在于调用的 Lambda 函数的最大值,这些函数可以被 ECS 容器替换,并定义了最大资源为您完成这项工作。请参阅:https ://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html 。

第二个问题:ItemPath 允许您在数组中传递参数。请参阅 ItemPath:https ://docs.aws.amazon.com/step-functions/latest/dg/input-output-itemspath.html

编辑:AWS 文档中使用带有 Lambda 的 Map 的示例https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-creating-map-state-machine.html

于 2019-10-14T22:11:36.650 回答
0

第一个问题:你基本上是对的。您可以做的其他事情是要求 AWS 支持增加某些函数的并行 Lambda 执行。请参阅“请求增加限制”:https ://docs.aws.amazon.com/lambda/latest/dg/limits.html无论如何,请确保每个函数并行执行(即在有效负载项上插入一个循环,因此每个函数都会执行多次)。

第二个问题:如果您不想将有效负载移交给每个功能,您可以针对某些功能对其进行过滤:https ://docs.aws.amazon.com/step-functions/latest/dg/amazon- states-language-input-output-processing.html因此,您可以仅针对特定功能过滤掉地址等。

于 2018-02-13T07:30:08.600 回答
0

坏消息是 AWS Step 中的愚蠢并行化仍然是一个悬而未决的问题,请参阅:https ://forums.aws.amazon.com/thread.jspa?threadID=244196&start=0&tstart=0

好消息是,AWS 在 2017 年 11 月引入了对Array JobsAWS Batch 的支持,请参阅:https ://aws.amazon.com/about-aws/whats-new/2017/11/aws-batch-adds-support-for - 大规模作业提交/。数组作业允许ProcessRecord-Task-?对.forsubmitJobWith(start, BATCH_RECORD_SIZE)

于 2018-10-22T20:17:53.803 回答