AWS Lambda - Nodejs:分配失败 - JavaScript堆内存不足

时间:2018-04-19 12:51:26

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

我正在使用Lambda(nodeJS)来查询noSQL数据(dynamo db)。

假设我在DynamoDB中有表“student”,并且我有一个API,它返回特定类(class_id)的学生列表。 (我用“查询”)

据我所知,dynamo对结果进行分页,因此我的API的工作原理如下:

  • {class_id : 'xxxx'} =>返回第一份学生名单
  • {class_id : 'xxxx', last_evaluated_key: { ....} =>返回下一个学生列表(如果LastEvaluatedKey存在)

我的lambda代码:

exports.handler = function(e, ctx, callback) {
    var rp = require('request-promise');

    var students = [];

    var hasMore = true;
    var params = {
        class_id: e.class_id
    }

    while (hasMore) {
        var options = {
            method: 'POST',
            uri: 'https://xxxxxx.eu-west-1.amazonaws.com/dynamodliblightdm-gobject-1-0:amd64liblightdm-gobject-1-0:amd64b/getStudents',
            body: params,
            json: true // Automatically stringifies the body to JSON
        };

        rp(options)
            .then(function(repos) {
                console.log('count: ' + repos.Count);
                students.push(repos.Items);

                if (repos.hasOwnProperty("LastEvaluatedKey")) {
                    params['last_evaluated_key'] = repos.LastEvaluatedKey;
                } else {
                    hasMore = false;
                }

            })
            .catch(function(err) {
                console.log('Error', err);
            });
    }


    callback(null, 'done.');
}

我收到了错误:

  

42676 ms:标记扫描804.1(954.3) - > 802.7(954.3)MB,1803.0 / 0.0   ms(自标记开始以来的32个步骤中+ 246.3 ms,最大步骤35.7   ms)[分配失败] [请求旧空间中的GC]。       44415ms:标记扫描802.7(954.3) - > 802.7(954.3)MB,1738.6 / 0.0 ms [分配失败] [请求旧空间中的GC]。       46318ms:标记扫描802.7(954.3) - > 809.5(859.3)MB,1902.9 / 0.0 ms [last resort gc]。       48184ms:标记扫描809.5(859.3) - > 816.4(858.3)MB,1865.7 / 0.0 ms [最后的手段gc]。       < --- JS stacktrace --->       ==== JS堆栈跟踪=========================================       安全上下文:0x322e8723fa99       2:新构造函数(又名Multipart)[/var/task/lambda-func/node_modules/request/lib/multipart.js:~8]   [pc = 0x1b47df3f5f98](这= 0x1175e583149,请求= 0x1175e582fa9)       4:新构造函数(又名请求)[/var/task/lambda-func/node_modules/request/request.js:125]   [pc = 0x1b47df4df3e6](这= 0x1175e ......       致命错误:CALL_AND_RETRY_LAST分配失败 - JavaScript堆内存不足       1:node :: Abort()[/ var / lang / bin / node]       2:0x55d79ff0b302 [/ var / lang / bin / node]       3:v8 :: Utils :: ReportApiFailure(char const *,char const *)[/ var / lang / bin / node]       4:v8 :: internal :: V8 :: FatalProcessOutOfMemory(char const *,bool)[/ var / lang / bin / node]       5:v8 :: internal :: Factory :: NewFillerObject(int,bool,v8 :: internal :: AllocationSpace)[/ var / lang / bin / node]       6:v8 :: internal :: Runtime_AllocateInTargetSpace(int,v8 :: internal :: Object **,v8 :: internal :: Isolate *)[/ var / lang / bin / node]       7:0x1b47df2062bf

任何建议都表示赞赏。

1 个答案:

答案 0 :(得分:1)

建议让所有学生。

const fetch  = (lastEvaluatedKey)  => {
  return rp().then((res) => {
    students = students.concat(res.moreStudents);
    if(res.shouldKeepFetching) {
      return fetch(res.lastKey);
    }

    return Promise.resolve();
  })
}

fetch().then(() => {
  //you fetched them all
})

如果有一大堆学生,这可能会让你遇到另一个内存不足的问题。 你可以做的另一件事,但我不知道lambda是否允许它,是使用带有async / await的for循环