好吧,已经过了大约10个小时,我仍然无法解决这个问题。有人可以帮忙吗?每次调用Node / Express API时,我都会写Redis和MongoDB。但是,当我使用相同的密钥查询每个数据库时,Redis会逐渐开始错过记录。我可以通过限制整体吞吐量来减少这种行为(减少我要求Redis做的操作#)。这是伪代码:
function (req, res) {
async.parallel {
f {w:1 into MongoDB -- seems to be working fine}
f {write to Redis -- seems to be miss-firing}
这里是Redis代码:
var trx = 1; // transaction is 1:pending 0:complete
async.whilst(function(){return trx;},
function(callback){
r.db.watch(key);
r.db.hgetall(key, function(err, result){
// update existing key
if (result !== null) {
update(key, result, req, function(err, result){
if (err) {callback(err);}
else if (result === null) {callback(null);}
else {trx = 0; callback(null);}
});
}
// new key
else {
newSeries(bin, req, function(err, result){
if (err) {callback(err);}
else if (result === null) {callback(null);}
else {trx = 0; callback(null);}
});
}
});
}, function(err){if(err){callback(err);} else{callback(null);}}
);
在"更新"和" newSeries"函数,我基本上只是使用来自HGETALL的值进行MULTI / EXEC redis,并返回结果(以确保我没有遇到竞争条件)。
我正在使用Cluster with Node,所以我有多个线程一次执行到Redis。 任何想法都会非常有用。感谢。
答案 0 :(得分:0)
我想我只是需要一点睡眠,而且需要更多的记录来解决这个问题。
基本上,它是我的代码块上方的async.each循环。因为它并行运行,EXEC有时被称为不同的键!所以它会在另一把钥匙上擦掉手表!所以,我只需要将它切换到async.eachSeries - 这可以确保我的单个节点工作者不会工作" (同时观看&EXEC;和EXEC')多个键!
所以,第一个重要的经验教训:首先,来自连接的任何EXEC命令都会清除所有WATCH命令(因此对并行或异步处理要非常小心)。
第二,对async.each非常非常小心,并且始终默认为async.eachSeries!对我来说,async.each在概念上非常强硬 - 它确实可以搞砸单线程进程(比如Redis)。在过去的一年里,这花费了我很多时间和痛苦......小心!
希望这可以帮助那些人。