我有一个程序可以执行数千次蒙特卡洛模拟来预测结果。我不能说他们真正预测了什么,所以我将使用“毫无争议的圣诞老人的存在”中的另一个例子,因为这些算法的内容与问题无关。我想知道专卖板上的每个广场访问的频率(以预测要购买的最佳房产是哪个)。为此,我模拟了数千个游戏并整理了结果。我当前的实现是一个独立的C#应用程序,但我想将其移动到云中,以便我可以将其作为服务提供-每个用户都可以通过提交每个骰子的边数来获得个性化的结果。
当前的实现也很慢-它非常可笑,因为每个模拟都是完全独立的,但是我只有8个内核,因此在我的本地计算机上用大约50000个单独的模拟完成完整的预测需要花费20分钟以上的时间。
计划是让AWS lambda函数每个运行一个(或几个)模拟,然后进行整理(基本上是mapreduce)。我考虑使用AWS EMR(Elastic MapReduce),但这对于我想要的来说规模太大了,将实例分解为单独运行计算似乎比单独进行整个计算要花费更长的时间(对于多小时离线分析,但我希望低延迟响应Web请求)。
我认为理想的是:
Lambda 0-触发许多其他lambda函数,每个函数只占计算的一小部分。Lambda 1..N-并行执行许多模拟(数字不是常数)。Lambda N + 1-整理所有结果并返回答案。
这里有一个lambda mapreduce框架:
https://github.com/awslabs/lambda-refarch-mapreduce
但这似乎有一个主要缺点-每次映射阶段完成时,它都会将其结果写入S3(我可以临时使用它),然后通过一个事件触发一个新的lambda。触发的lambda会查看是否所有结果都已写入存储。如果不是,则结束,如果是,则进行减少步骤。这似乎是一个公平的解决方案,但我只是稍微担心一下:a)当两个结果放在一起时会产生比赛危险,两个减速器都可以计算结果吗?b)似乎正在淘汰很多只决定不运行的lambda(我知道它们运行起来很便宜,但每个模拟将其数量翻倍至两倍-计算并可能减少-显然会使成本增加一倍) )。例如,将100个文件写入一个文件夹而不是每次写入一个文件之后,是否有办法触发S3结果?
我看过使用步进函数,但不确定如何在一步中并行触发许多lambda,并在状态机转换之前让它们全部返回。但是,Step函数对于最后的皱纹很有用-我想将所有这些隐藏在API后面。
根据我的阅读,API可以触发一个lambda并返回该lambda的结果,但是我不希望被调用的lambda成为返回结果的那个。并不是当您改为从API调用step函数时,而是由API调用返回了最后一个状态的结果。
简而言之,我要:
API请求->并行计算结果-> API响应
只是中间的一点我不清楚如何去做,同时能够返回所有结果作为对原始请求的响应-要么很简单。
我可以看到一些选择:
使用现在由AWS API网关本地支持的step函数,并在一种状态下调用多个lambda,等待它们全部返回后再进行转换。
使用AWS EMR,但以某种方式使已调配的实例始终处于活动状态,以避免调配时间的开销。这显然会否定Lambda的可伸缩性,并且价格更高。
使用mapreduce框架或类似的框架,找到一种方法来响应来自不同lambda的传入请求到最初由API请求调用的那个。理想情况下,还可以减少此处涉及的S3事件的数量,但这不是优先事项。
立即响应第一个lambda的原始API请求,然后在计算完成时将更多数据推送给用户(使用并行机制时,它们只需要大约30秒,而域是等待的可接受时间)响应,甚至是HTTP响应)。
我怀疑这对解决方案是否会有影响,因为这只是中间部分的扩展,而不是根本的更改,但是实际的计算是迭代的,因此将是:
请求-> Mapreduce-> Mapreduce-> …->响应
只要我知道如何在请求中链接一组lambda函数,链接更多就应该更多(我希望)。
谢谢。
PS我无法创建它们,并且既没有标签aws-emr也aws-elastic-mapreduce没有。