AWS Lambda中的递归调用/ fork调用

时间:2016-03-19 08:34:22

标签: node.js amazon-web-services aws-lambda

我在NodeJS中使用AWS Lambda。有了这个lambda,我想在DynamboDB中添加一本书。它工作正常。

现在,我想为图书清单做这件事。我有一些想法,但我不知道它是否可以在AWS lambda中使用。

想法1:分叉几个lamba

我想知道是否可以拥有一个"主人" Lambda有一个要添加的书籍列表, foreach书籍调用lambda函数"插入书籍#34;。最大超时为5分钟,因此可以从" master"进行异步调用。 lambda为了不等待所有分叉的lambda进程?

想法2:递归调用

创建一个通用lambda,处理作为输入传递的书籍列表的第一本书。在该过程结束时,从列表中删除该书(如果正常)并使用更新的List调用相同的lambda。

注意:第一次调用需要获取书籍列表。

非常感谢你的帮助!

罗曼。

3 个答案:

答案 0 :(得分:2)

我假设您处理的时间过长,以至于您无法在lambda函数的一次调用中添加多本书。

你可以扇出并递归调用你的lambda函数。 两者都有利有弊。

如果您经常散布太多,那么您的dynamodb写入可能会超出配置的写入容量。

如果递归调用函数,则无法向调用者返回值。 (假设整个通话链需要超过五分钟。)

答案 1 :(得分:2)

听起来你的问题是你没有拥有计算的上下文。使用'master'lambda肯定会解决这个问题。如何进行调用有几种不同的解决方案。

  1. 对于列表中的每本书,发布到'child'-lambda订阅的sns主题。这是一个如何使lambda订阅sns主题http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html的链接。要发布到sns主题,您只需使用AWS SNS SDK作为主lambda的语言。
  2. 使用AWS Lambda SDK在“master”lambda中调用lambdas。有关如何执行此操作的示例节点脚本如下所示:
  3. const Promise = require('bluebird');
    const AWS = require('aws-sdk');
    const lambda = Promise.promisifyAll(new AWS.Lambda({ apiVersion: '2015-03-31' }));
    
    const listOfBook = ['Book One', 'Book Two', 'Book Three'];
    
    const bookEntryStats = {
        successFullBookEntries: [],
        failedBookEntries: []
    };
    
    Promise.map(listOfBooks, function (book) {
    
        return lambda.invokeAsync({FunctionName: 'ChildLambdaFunctionName', Payload: new Buffer(book)}).then(function () {
            bookEntryStats.successFullBookEntries.push(book);
        }).catch(function () {
            bookEntryStats.failedBookEntries.push(book);
        });
    }, {concurrency: 20})
        .then(function () {
            console.log(bookEntryStats);
        });

    如果使用sns方法,您需要考虑在发布到sns主题的那一刻,当您“丢失”执行上下文时,很难控制执行的并发lambda数量。由于您可以同时执行多少个并发lambda的硬限制,如果书籍列表很长,您将很容易导致限制。

    第二种方法可能不那么优雅,但Promise.map函数的'concurrency'参数允许您控制在任何给定点执行的lambda函数数。

    希望这有帮助!

答案 2 :(得分:0)

我最近开始摆弄AWS Lambda并遇到了你的问题。我想通过Web服务调用(API Gateway)启动大批量(50000)作业。这项工作需要尽快完成,即开销时间加上一项工作完成所需的时间。

我有这个想法:

一个。两个功能。

  • Lambda函数名为 worker ,使用有效负载数据执行工作。

  • 名为调度程序的Lambda函数调用自身或 worker

B中。最初是一个有效载荷。

使用对象列表作为有效负载调用Web服务,每个对象包含工作者完成工作所需的数据。 Web服务将有效负载交给第一个调度程序

℃。 Dispatcher 不返回任何内容,而是使用可轮询的Web服务调用来检查所有作业的状态。

所以,例如。

您使用JSON有效内容中的50000个对象调用Web服务,Web服务首先调用调度程序。当然,调度程序无法按顺序迭代所有这些,而不会达到(AWS Lambda)的最大执行时间,因此它会将传入列表拆分为10个新列表。这意味着下一个调度程序现在被调用10次,每个调度程序都有一个大小为5000的对象列表。

调度程序继续执行此操作,直到他们持有如此多的小对象列表,您信任它可以开始迭代列表,为每个对象调用 worker 函数它们。

因此,如果调度程序配置为仅在传入列表为10个或更少的对象时执行作业,在此示例中,5000 调度程序将逐个迭代它&#39 ;列出10个对象,调用执行该作业的 worker lambda函数。

这是我的想法,我现在正在与之合作。我不确定是否会达到我不知道的任何AWS限制。我知道设置限制,例如调用Lambda函数时的有效负载大小,最大执行时间等。

理论上,这可以无限扩展。