所有 Redis 命令都是异步的吗?
Posted
技术标签:
【中文标题】所有 Redis 命令都是异步的吗?【英文标题】:Are all Redis Commands Asynchronous? 【发布时间】:2016-01-16 03:35:59 【问题描述】:我是 Redis 和 Node.JS 的新手,一直在尝试将两者结合使用。但是我有点困惑,我可以一个接一个地使用哪些功能。
以下代码似乎是同步运行的,随着数据库大小的增加:
client.dbsize(function(err, numKeys)
console.log("DB Size before hashes added" + numKeys);
return numKeys;
);
for (var i = 0; i < 100; i++)
client.hmset(i, "username", "username", "answer", "answer");
client.zadd('answer', i, i);
;
client.dbsize(function(err, numKeys)
console.log("DB Size after hashes added" + numKeys);
return numKeys;
);
但是,当我尝试查询已排序的集合“answer”以返回一个数组时,该数组“reply”不能立即用于“zrevrangebyscore”回调之外的其他 redis 函数。
client.zrevrangebyscore('answer', 100, 0, function(err, reply)
console.log (reply);
return reply;
);
例如,在回复[1] 上调用的后续“hgetall”函数返回未定义。我应该通过回调/client.multi 等异步方式使用所有 Redis 函数(包括 hmset 和 dbsize),或者如果同步使用,则可以有效地工作?感谢所有帮助。
【问题讨论】:
【参考方案1】:当谈到同步和异步代码时,您似乎很困惑。我建议您尽可能多地阅读,直到它“点击”为止。 我将举例说明问题所在以及原因:
//we're going to fake the redis dbSize function
var dbSize = function(callback)
//always finishes asynchronously
console.log("dbsize called");
setTimeout(callback, 1000);
;
//here we get to your code
dbSize(function()
console.log("First callback");
);
console.log("synchronous redis method calls");
//here come the synchronous redis methods, that finish synchronously
dbSize(function()
console.log("Second callback");
);
现在,如果您 run this code 它会向控制台输出以下内容:
"dbsize called"
"synchronous redis method calls"
"dbsize called"
"First callback"
"Second callback"
如您所见,同步方法被调用,在异步方法完成。所以,所有要做的就是确保您调用同步方法之后,这将在第一个回调中,即您必须将这些东西链接在一起。 现在这很混乱,因为它会将您带入回调地狱:
dbSize(function()
console.log("First callback");
console.log("synchronous redis method calls");
//here come the synchronous redis methods, that finish synchronously
dbSize(function()
console.log("Second callback");
);
)
因此,为避免这种情况,最好使用 async lib 之类的东西
async.series([
function(next)
dbSize(next);
,
function(next)
console.log("synchronous redis method calls");
//here come the synchronous redis methods, that finish synchronously
next();
,
function(next)
dbSize(next);
,
], function()
console.log('All done!');
)
这将输出:
"dbsize called"
"synchronous redis method calls"
"dbsize called"
"All done!"
【讨论】:
感谢您的回答,帮了大忙!【参考方案2】:Redis is single-threaded,所以Redis 上的命令总是按顺序执行。看起来您可能正在为 Redis 使用异步客户端,这就是混乱的来源。因为您无法保证网络延迟,所以如果您使用异步 Redis 客户端,则稍后的调用可能会在之前的调用之前到达 Redis 服务器并导致您遇到问题。对于 Redis 的异步客户端为什么存在 here,有一个很好的解释。
综上所述,在您的案例中,重要的一点是,如果您希望您的命令保证同步运行,您有几个选择:
-
在 Redis 中使用 pipeline 可以让您的所有命令只与服务器进行一次往返(无论如何,这可能是个好主意,除非您需要在命令之间做一些事情)。
使用异步库,如文档中的 here。
使用同步 Redis 客户端。我对 Node.js 的了解还不够,无法知道它的可行性。
【讨论】:
感谢您的回答,帮了大忙!以上是关于所有 Redis 命令都是异步的吗?的主要内容,如果未能解决你的问题,请参考以下文章