AWS Step Functions与批处理限制

5
场景:需要处理大量小型记录(约10k个),每个记录平均大小为50字节。为了提高性能,必须以并行或其他方式进行处理(记住,我们有很多记录要处理)。此外,处理本身是非常简单的任务(这就是使用AWS Lambda的原因之一)。尽管它很简单,但有些处理可能会在其他处理之前/之后结束,因此这就是为什么这些记录彼此独立且处理顺序不重要的另一个原因。

到目前为止,Step Functions看起来是最好的选择。

使用Step Functions,我们可以拥有以下图形:

enter image description here

我可以将RecordsRetrieval定义为一个任务。之后,这些记录将由ProcessRecords-Task-1、ProcessRecords-Task-2和ProcessRecords-Task-3的任务并行处理。看起来一切都很好,对吗?错了!

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

无论如何,对于像GetAddress、GetPhoneNumber、GetWhatever这样明确定义的一组并行任务来说,这是非常好的!完美运作!

第二个问题:有效载荷分发 在RecordsRetrieval任务之后,我需要单独处理每个记录。使用Step Functions,我没有看到任何实现这一点的方法。一旦RecordsRetrieval任务传递其有效载荷(在本例中为这些记录),所有并行任务都将处理相同的有效载荷。

再次强调,对于像GetAddress、GetPhoneNumber、GetWhatever这样明确定义的一组并行任务来说,这将是完美的匹配。

结论 我认为,可能AWS Step Functions不是我的场景的解决方案。这是我对它的了解的总结,所以如果我漏掉了什么,请随时评论。

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

我知道可以检索这些记录并将其逐个发送到另一个lambda,但再次强调,这不是一个非常优雅的解决方案。

我也知道这是批处理作业,AWS有批处理服务。我正在尝试保持微服务方法,而不依赖于AWS Batch/EC2。

你对此有何看法?欢迎留言评论。任何建议都将不胜感激。

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 Batch进行此处理。


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

映射类型对于大型负载具有限制。 - weiheng

0

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

好消息是,2017年11月,AWS 在 AWS Batch 中引入了对Array Jobs的支持,参见:https://aws.amazon.com/about-aws/whats-new/2017/11/aws-batch-adds-support-for-large-scale-job-submissions/。数组作业允许对ProcessRecord-Task-?进行愚蠢的并行化,基本上就是@Rishikesh Darandale使用for循环和submitJobWith(start, BATCH_RECORD_SIZE)所做的。


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 因此,你可以仅针对特定的函数过滤出地址等内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接