场景:必须处理一小堆(每个平均50字节)的记录(如10k,可能更多)。处理必须以并行或任何其他方式完成以提高性能(记住,我们有很多记录要经历)。此外,处理本身是一项非常简单的任务(这是使用AWS Lambda的原因之一)。虽然它很简单,但某些处理可能会在其他处理之前/之后结束,因此这些记录的另一个原因是 相互独立,处理顺序无关紧要。
到目前为止,Step Functions看起来像是要走的路。
使用步骤函数,我们可以得到以下图表:
我可以将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。
您对此有何看法?随意评论。任何建议将不胜感激。
答案 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;
}
您可以使用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文档中的示例