Amazon dynamodb 动力-运动流

Amazon dynamodb 动力-运动流,amazon-dynamodb,aws-lambda,amazon-kinesis,amazon-dynamodb-streams,Amazon Dynamodb,Aws Lambda,Amazon Kinesis,Amazon Dynamodb Streams,我有一个向DynamoDB表写入数据的应用程序,我试图让Kinesis进行聚合,然后将聚合的数据写入另一个DynamoDB表 在我的DynamoDB表上启用了流,我在流上有一个Lamdba触发器,如下所示: “严格使用”; var AWS=要求('AWS-sdk'); var-kinesis=新的AWS.kinesis(); exports.handler=(事件、上下文、回调)=>{ event.Records.forEach((记录)=>{ var myValue=record.dynamo

我有一个向DynamoDB表写入数据的应用程序,我试图让Kinesis进行聚合,然后将聚合的数据写入另一个DynamoDB表

在我的DynamoDB表上启用了流,我在流上有一个Lamdba触发器,如下所示:

“严格使用”;
var AWS=要求('AWS-sdk');
var-kinesis=新的AWS.kinesis();
exports.handler=(事件、上下文、回调)=>{
event.Records.forEach((记录)=>{
var myValue=record.dynamodb.NewImage.myValue.N;
var partitionKey=record.key.S;
变量数据='{“值”:“'+myValue+'“}”;
变量记录参数={
数据:数据,
PartitionKey:PartitionKey,
StreamName:“MyStreamName”
};
log('Try Put to Kinesis Stream');
kinesis.putRecord(记录参数,函数(错误,数据){
如果(错误){
log('Failed Put');
}否则{
log('successfullput');
}
});
});
};
当Lambda测试事件中有三个或四个元素时,这将成功写入我的Kinesis流

当我启用触发器时,它根本不会写入我的运动流。一次似乎有大约100个元素进入。在Cloudwatch中,我看到了“Try Put to Kinesis Stream”消息,但我甚至没有看到成功/失败消息

我是做错了什么,还是有更好的方法来解决这个问题


如果DynamoDB的流可以直接输入到Kinesis Analytics中,那将是我的头奖:)

您的错误在于lambda函数没有等到所有的Kinesis.putRecord调用完成

在Node.js中,您有一个回调的编程模型。您发出一个异步请求,请求完成时将调用回调。因此,当函数返回时,请求未完成。当调用回调时,它就完成了

有两种解决方案:

自己跟踪被调用的回调

'use strict';
var AWS = require('aws-sdk');
var kinesis = new AWS.Kinesis();
exports.handler = (event, context, callback) => {
    event.Records.forEach((record) => {
        var myValue = record.dynamodb.NewImage.myValue.N;
        var partitionKey = record.key.S;
        var data = '{"VALUE":"' + myValue + '"}';
        var recordParams = {
            Data: data,
            PartitionKey: partitionKey,
            StreamName: 'MyStreamName'
        };
        console.log('Try Put to Kinesis Stream');
        var i = 0;
        kinesis.putRecord(recordParams, function(err, data) {
            if (err) {
                console.log('Failed Put');
                i = event.Records.length;
            } else {
                console.log('Successful Put');
                i += 1;
            }
            if (i === event.Records.length) {
                console.log('All done');
                callback(err);
            }
        });
    });
};

或者使用类似async的库:

在我看来,整体问题的一部分(除了需要调用
回调
,per
hellomichibye
)以及您在注释中描述的行为,可能来自于您如何为
数据
构建值。不要手动为
数据创建JSON字符串
,请尝试使用,以便知道输入的格式始终正确。

这对小型数据对象“{”VALUE:“12345”}”有效,但只要我添加了更多属性(我的对象具有>6个属性),就不会将任何记录写入流。我在周末禁用了Kinesis应用程序,现在又尝试了一次,似乎可以正常工作。我现在唯一担心的是它再次这样做,并不是所有的记录都被传送到流中。它平稳地运行了4个小时,然后没有任何东西被写入到Kinesis流中。我增加了函数的超时时间,这似乎有所帮助,但在第一个超时请求之后,似乎每个后续请求都超时了。不知道为什么,因为大多数批处理都很小。您应该使用异步库。在一个数组上执行forEach是不安全的,在该数组中,您正在执行异步调用。您需要将整个过程与要执行的异步库协调:
async.mapLimit(event.Records、5、putinotkinesis、callback)
或类似的操作。另一个选择是,您可以将项目批量放入动态,而不必进行大量的单独写入。