我正在使用nodeJS 6.3.0和aws DynamoDB编写应用程序。
dynamodb保存添加到dynamodb的统计信息,这些信息是从10个不同的函数(10种不同的统计量度)调用的。间隔设置为10秒,这意味着每10秒钟,我将对我的函数进行10次调用以添加所有相关信息。
putItem函数:
function putItem(tableName,itemData,callback) {
var params = {
TableName: tableName,
Item: itemData
};
docClient.put(params, function(err, data) {
if (err) {
logger.error(params,"putItem failed in dynamodb");
callback(err,null);
} else {
callback(null,data);
}
});
现在......我创建了一个队列。
var queue = require('./dynamoDbQueue').queue;
实现了一个我从http://www.bennadel.com/blog/2308-creating-a-fixed-length-queue-in-javascript-using-arrays.htm获取的具有固定大小的简单队列。
这个想法是,如果存在网络问题..让我们说一分钟。我希望将所有事件推送到队列中,并在问题解决后将队列信息发送到dynamodb并释放队列。
所以我将原来的函数修改为以下代码:
function putItem(tableName,itemData,callback) {
var params = {
TableName: tableName,
Item: itemData
};
if (queue.length>0) {
queue.push(params);
callback(null,null);
} else {
docClient.put(params, function (err, data) {
if (err) {
queue.push(params);
logger.error(params, "putItem failed in dynamodb");
handleErroredQueue(); // imaginary function that i need to implement
callback(err, null);
} else {
callback(null, data);
}
});
}
}
但由于我有10个插入函数在同一秒运行,因此存在竞争条件。这意味着......
execute1 - 一个验证队列为空的函数......即将执行docClient.put()
函数。
execute2 - 同时另一个函数从docClient.put()
返回并出现错误,因此它将第一行添加到队列中。
execute1 - 当第一个函数调用docClient.put()
时,问题已经解决,并且成功地将数据插入到dynamodb中,这使得队列具有将在下一次迭代中释放的先前数据。
因此,例如,如果我插入带有1,2,3,4
的4行,则将插入到dynamodb的行的顺序为1,2,4,3
。
有办法解决这个问题吗?
谢谢!
答案 0 :(得分:2)
我认为你处于正确的轨道,但我没有检查错误然后添加到队列中,我建议先将每个操作添加到队列中,然后每次都从队列中读取数据。
例如,在您的情况下,您调用函数1,2,3,4并导致1,2,4,3,因为您在错误/突然操作时一直使用队列。
Step1: All your function will make an entry to a Queue -> 1,2,3,4
Step2: Read your queue and make an insert, if success remove the element
else redo the operation. This way it will insert in the desired sequence
另一个优点是,因为您正在使用队列,所以不必为表保持非常高的吞吐量。
修改强>:
我想您只需要确保在完成第一次操作后,您将执行下一个过程,而不是在此之前。
例如:fn 1 - >从队列中读取(不要立即从队列中删除) - >操作如果没有再次执行则完成 - >从队列中删除 - >执行下一步操作。
您必须确保从队列中读取并等待您从DynamoDB获得响应。
希望这有帮助。