具有批处理限制的AWS步骤函数

时间:2018-02-10 19:19:11

标签: amazon-web-services aws-lambda aws-step-functions

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

到目前为止,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任务传递了它的有效负载 (在这种情况下是那些记录),所有并行任务都将处理相同的有效负载。

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

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

我正在挖掘微服务方法有很多原因(可伸缩性,无服务器,简单等等)。

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

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

您对此有何看法?随意评论。任何建议将不胜感激。

4 个答案:

答案 0 :(得分:2)

根据您的意见,根据我的说法,以下解决方案可以与您的标准一致。您可以使用AWS lambda或AWS批处理来获得以下解决方案。

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将调用/提交批处理作业no =(总记录数)/(每个作业/ lambda调用没有记录)。
  • 如果您更喜欢lambda,那么定义lambda,使得它需要两个参数start和limit作为输入。这些参数将决定从哪里开始读取要处理的文件以及停止的位置。这个lambda也会知道从哪里读取记录。
  • 如果您更喜欢批处理,请使用与上述相同的逻辑定义作业定义。

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

答案 1 :(得分: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因此您可以过滤掉地址等,仅用于具体功能。

答案 2 :(得分: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)中所做的。

答案 3 :(得分:0)

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

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

相关问题