我有一个写入DynamoDB表的应用程序,我试图让Kinesis进行聚合,然后将聚合数据写入另一个DynamoDB表。
我的DynamoDB表上启用了流,我在流上有一个Lamdba触发器,如下所示:
'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');
kinesis.putRecord(recordParams, function(err, data) {
if (err) {
console.log('Failed Put');
} else {
console.log('Successful Put');
}
});
});
};
当我在Lambda测试事件中有三个或四个元素时,这会成功写入我的Kinesis Stream。
当我启用触发器时,它根本不会写入我的Kinesis Stream。似乎一次有大约100个元素进入。在Cloudwatch中,我看到了“尝试放入Kinesis Stream'消息,但我甚至看不到成功/失败消息。
我做错了什么或有更好的解决方法吗?
如果DynamoDB的流可直接提供给Kinesis Analytics,那将是我的第一奖:)
答案 0 :(得分:4)
你的错误是你的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这样的库:https://www.npmjs.com/package/async
答案 1 :(得分:0)
在我看来,你的整体问题的一部分(除了需要调用callback
,每个hellomichibye
)以及你在评论中描述的行为,可能来自你如何构建价值Data
。不要手动为Data
创建JSON字符串,而是尝试使用JSON.stringify,以便您知道输入将始终正确格式化。