AWS Lambda函数如何更新DynamoDB表中的所有记录?

时间:2017-03-30 01:36:21

标签: javascript node.js asynchronous amazon-dynamodb aws-lambda

我正在使用AWS Lambda函数(Node 4.3),该函数需要遍历DynamoDB表中的所有项并更新某些属性。

我遇到的问题是如何让Lambda等到所有DynamoDB操作完成。

var async = require('async');
var aws = require('aws-sdk');
var doc = new aws.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {
    doc.scan({
        TableName: 'Occupations_dev'
    }, function (err, data) {
        console.log(data.Items.length);

        var funcs = [];

        data.Items.forEach(function (item) {
            funcs.push(function (cb) {
                item.Popularity = 0;

                doc.put({
                    TableName: 'Occupations_dev',
                    Item: item
                }, function (err, data) {
                    if (err) {
                        console.log("ERROR: " + item.Name);
                        cb(err);
                    } else {
                        console.log('Finished put for ' + item.Id)
                        cb(null, item);
                    }
                });
            });
        });

        async.parallel(funcs, function (err, results) {
            console.log('Finished');

            if (err) {
                context.fail(err);
            } else {
                callback(null, 'Finished');
            }
        });
    });
};

我尝试使用async.parallel等待所有db.put个请求完成,但只要Lambda函数运行,它就会以Process exited before completing request错误结束。

它会更新一些的DynamoDB项目,但绝对不是全部。

我在错误时添加了一些console.log次调用,但我在日志中看到的唯一输出是:

START RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870 Version: $LATEST
2017-03-30T02:08:11.691Z    b72fd7c6-14ed-11e7-a95a-c1185af4e870    1362
END RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870
REPORT RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870  Duration: 37165.80 ms   Billed Duration: 37200 ms   Memory Size: 128 MB Max Memory Used: 128 MB 
RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870 Process exited before completing request

使Lambda函数等到完成所有操作的正确方法是什么? (这不是一个庞大的数据量,所以我不担心运行超过5分钟并超时。)

2 个答案:

答案 0 :(得分:1)

消息“在完成请求之前退出进程”表示在调用context.done(或context.succeed等)之前退出Javascript函数。

以下是一些建议:

首先,尝试增加该功能的内存限制。这一行Memory Size: 128 MB Max Memory Used: 128 MB可能表示内存不足,并且该进程在没有调用最后一个回调的情况下被杀死。

增加内存限制后,您可能会看到以下内容之一:

  • 您的功能会超时。在这种情况下,您可能需要增加表的预配置容量(和/或lambda超时)

  • 即使函数没有超时结束,您可能会看到并非处理完所有表记录。这是因为如果扫描项目的总数超过最大数据集大小限制1 MB,则扫描和查询操作可能不会返回所有表的行。扫描完成后,您应检查LastEvaluatedKey是否与数据一起返回。如果是,则应进行另一次扫描,将LastEvaluatedKey值作为ExclusiveStartKey参数

答案 1 :(得分:1)

async.parallel函数调用是异步发生的,这可能会使DynamoDB多次同时更新,并在数据库级别引发“太多连接”错误

我建议使用async.series之类的同步操作来执行数据库更新。 DynamoDB应该不会一个接一个地处理这些更新。