Y_L*_*ess 12 amazon-web-services aws-lambda aws-api-gateway aws-step-functions
我有一个程序执行几千蒙特卡罗模拟来预测结果; 我不能说他们真正预测的是什么,所以我将使用"无可争议的圣诞老人存在"中的另一个例子,因为这些算法的内容与问题无关.我想知道Monopoly董事会上每个广场的访问频率(预测哪些是最好的购买物业).为此,我模拟了数千个游戏并整理结果.我目前的实现是一个独立的C#应用程序,但我想将它移动到云端,以便我可以将其作为服务提供 - 每个用户都可以通过提交每个骰子的边数来获得个性化结果.
当前的实现也非常慢 - 它非常简单,因为每个模拟都是完全独立的,但我只有8个内核,因此在我的本地机器上完成大约50000个单独模拟的完整预测需要20分钟.
计划是让AWS lambda函数运行一个(或几个)模拟然后整理 - 基本上mapreduce它.我查看了使用AWS EMR(弹性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)看起来好像它已经解雇了很多只是决定不运行的lambdas(我知道它们运行起来很便宜,但是每次模拟的数量加倍到两次 - 计算并且可能会减少 - 显然会使成本增加一倍).有没有办法在100个文件写入文件夹而不是每个文件后写入S3结果?
我看了一下使用步骤函数,但是我不确定如何在一步中并行激发多个lambdas并让它们在状态机转换之前全部返回.然而,步骤函数对于最终的皱纹是有用的 - 我想在API后面隐藏所有这些.
根据我的阅读,API可以触发lambda并返回该lambda的结果,但我不希望被调用的lambda是返回结果的lambda.当您从API调用步骤函数时,不是API调用返回最后一个状态的结果.
总之,我想:
API请求 - >并行计算结果 - > API响应
中间的那一点我不清楚该怎么做,同时能够将所有结果作为对原始请求的响应返回 - 或者单独使用它们很容易.
我可以看到几个选项:
使用现在由AWS API网关本机支持的步骤函数,并在一个状态中调用多个lambda,等待它们在转换之前返回.
使用AWS EMR,但以某种方式保持配置的实例始终处于活动状态以避免配置时间开销.这显然否定了Lambda的可扩展性并且更加昂贵.
使用mapreduce框架或类似的东西,找到一种方法来响应来自不同lambda的传入请求到API请求最初调用的请求.理想情况下还要减少此处涉及的S3事件的数量,但这不是优先事项.
立即响应来自第一个lambda的原始API请求,然后在计算完成后将更多数据推送给用户(它们应该只需要大约30秒的并行性,并且域是这样的,这是可以接受的等待时间响应,甚至HTTP响应).
我怀疑它会对解决方案产生任何影响,因为它只是中间位的扩展,而不是根本的改变,但真正的计算是迭代的,所以会是:
请求 - > Mapreduce - > Mapreduce - > ... - >响应
只要我知道如何在一个请求中链接一组lambda函数,链接更多应该更多相同(我希望).
谢谢.
PS我无法创建它们,标签aws-emr也不aws-elastic-mapreduce存在.
有趣的情况..喜欢阅读问题的细节..基本上,我们正在寻找CPU功率负载,但持续时间很短......并且应该很快可用..如果我们真正意识到lambda的基本问题是它不支持线程并且不支持异步行为。
想一想.. Lambda 看起来是正确的方法.. 如果你使用 dynamodb 的帮助(不是另一个数据库,因为需求很小;为什么要为此拥有另一个 ec2 实例)呢? .. 每当 lambda 函数完成时,它就会并更新 dynamodb 中的记录..如果 db 中的该值大于 100 --> 执行最终的 lambda 函数..
数量固定为100吗?或者它可以是任何数字..如果它可以是任何数字n;然后我也可以想出解决方案来处理这个问题..
解决“api 调用发生在 lambda 0 上并且您需要对此进行回复”的问题的解决方案是 lambda 0 应该如下所示:
for ( int i = 0 ; i < n ; i++){
invoke processinglambda[i]; // each processingLambda process and updates
// results in dynamodb
}
while (true) {
(if work is done by ALL processing lambdas){
//collate all data
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我们基本上尝试使用上述设计来实现 MapReduce。 Lambda 0 是主节点;它将作业委托给节点 lambda 1..N... 进行处理并在 dynamodb 中不断更新结果 .. 主节点;如果所有子节点都完成工作,则继续查询 dynamodb。一旦完成;主节点整理所有数据并返回响应。
| 归档时间: |
|
| 查看次数: |
472 次 |
| 最近记录: |