【问题标题】:How can an AWS Lambda function update all records in a DynamoDB table?AWS Lambda 函数如何更新 DynamoDB 表中的所有记录?
【发布时间】:2017-08-23 17:41:17
【问题描述】:

我正在开发一个 AWS Lambda 函数(节点 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 分钟而超时。)

【问题讨论】:

  • 我想Process exited before completing request 表示您的 js 代码中还有其他错误 - 这是否在本地工作,并且只有 AWS Lambda 上的错误?
  • 我对 Lambda 比较陌生,所以我实际上不知道如何在本地运行它。有什么方法可以从 Lambda 获取更多错误详细信息?我在 CloudWatch 日志中看不到任何内容。
  • 奇怪,我相信他们应该在 Cloudwatch 中。当您运行代码 sn-p 时,您是否看到任何 console.log 语句?这些应该来自 Lambda 中的日志输出
  • 我添加了一些console.log 语句,用于当doc.put 出现错误但我没有看到任何日志。我只看到 console.log(data.Items.length); 的输出和大约 60 个 Finished put for... 语句在它死之前。
  • 狂野! DynamoDB 对同时连接有任何限制吗?如果您尝试异步插入太多记录,则可能会出错。也许尝试使用像 async.seriesPromise.all 这样的同步方法,看看你的结果是否相同。

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


【解决方案1】:

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

我建议使用同步操作,例如async.series 来执行数据库更新。 DynamoDB 一个接一个地处理这些更新应该没有问题。

【讨论】:

    【解决方案2】:

    消息“Process exited before completed request”表示Javascript函数在调用context.done(或context.succeed等)之前退出。

    以下是一些建议:

    首先,尝试增加函数的内存限制。这行Memory Size: 128 MB Max Memory Used: 128 MB 可能表示内存不足,进程直接被杀死,没有调用最后一个回调。

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多