Redis和Node.js以及Socket.io问题

我一直在学习redis和node.js有两个问题,我找不到任何满意的答案。

我的第一个问题是在node.js中重用redis客户端。 我发现这个问题和答案: 如何在socket.io中重用redis连接? 但是这并不足以让我满意。

现在,如果我在连接事件中创build了redis客户端,它将会为每个连接生成。 所以,如果我有20k个并发用户,那么会有20k个redis客户端。

如果我把它放在连接事件之外,它只会产生一次。

答案是说,他为连接事件之外的每个函数创build了三个客户端。

然而,从我所知道的MySQL来说,当编写一个产生subprocess并且并行运行的应用程序时,你需要在你创build子实例的函数中创build你的MySQL客户端。 如果你在它之外创build它,当subprocess尝试使用相同的连接时,MySQL会给出“MySQL服务器已经消失”的错误。 应该为每个subprocess分别创build。

所以,即使你为每个function创build了三个不同的redis客户端,如果你有3万个同时发送2k个消息的并发用户,你应该遇到同样的问题,对吧? 所以,每个“用户”都应该在连接事件中拥有自己的redis客户端。 我对吗? 如果不是,node.js或redis如何处理并发请求,与MySQL不同? 如果它有自己的机制并在redis客户端中创build类似subprocess的东西,为什么我们需要创build三个不同的redis客户端? 一个应该就够了。

我希望这个问题很清楚。

– 更新 –

我find了以下问题的答案。 http://howtonode.org/control-flow没有必要回答,但我的第一个问题仍然有效。

– 更新 –

我的第二个问题是这个。 我也不是很擅长JS和Node.js。 所以,据我所知,如果你需要等待一个事件,你需要在第一个函数内封装第二个函数。 (我不知道这个术语)。 让我举个例子;

socket.on('startGame', function() { getUser(); socket.get('game', function (gameErr, gameId) { socket.get('channel', function (channelErr, channel) { console.log(user); client.get('games:' + channel + '::' + gameId + ':owner', function (err, owner) { //games:channel.32:game.14 if(owner === user.uid) { //do something } }); } }); }); 

所以,如果我正确地学习,我需要运行function内的每个function,如果我需要等待I / O答案。 否则,node.js的非阻塞机制将允许第一个函数运行,在这种情况下,它会得到并行的结果,但第二个函数可能不会得到结果,如果需要时间。 所以,如果你从redis得到一个结果,你将在第二个函数中使用结果,你必须把它封装在redis get函数中。 否则第二个函数将运行而不会得到结果。

所以,在这种情况下,如果我需要运行7个不同的函数,而且这个函数需要所有这些函数的结果,那么我是否需要像这样recursion地写出它们呢? 还是我错过了一些东西。

我希望这一点也很清楚。

非常感谢,

所以,每个“用户”都应该在连接事件中拥有自己的redis客户端。 我对吗?

其实你不是:)

事情是,node.js是非常不像,例如,PHP。 node.js不会在新连接上产生subprocess,这是它可以轻松处理大量并发连接(包括长连接(Comet,Websockets等))的主要原因之一。 node.js使用一个单独进程中的事件队列按顺序处理事件。 如果要使用多个进程来利用多核服务器或多个服务器,则必须手动执行(不过,如何执行此操作超出了此问题的范围)。

因此,使用单个Redis(或MySQL)连接为大量客户端提供服务是完全有效的策略。 这避免了为每个客户端请求实例化和终止数据库连接的开销。

所以,每个“用户”都应该在连接事件中拥有自己的redis客户端。 我对吗?

您不应该为每个连接的用户创build一个新的Redis客户端,这不是正确的方法。 相反,只需创build2-3个客户端,然后使用它们。

欲了解更多信息结帐这个问题:

如何在socket.io中重用redis连接?

至于第一个问题:“正确的答案”可能会让你认为你有一个连接好。 实际上,当你正在等待一个IO,一个定时器等等时,你实际上是让节点在队列上运行等待方法。 因此,如果你只使用一个连接,你实际上会限制你工作的线程(单个CPU)的性能,以redis的速度 – 这可能是每秒几百个callback(非redis等待callback将仍然继续下去) – 虽然这不是糟糕的performance,但没有理由造成这种限制。 build议创build一些(5-10)连接以避免这个问题。 这个数字比较慢,比如MySQL,但是依赖于查询types和代码细节。

请注意,为了获得最佳性能,您应该在您的服务器上运行几个CPU,并根据您拥有的CPU数量运行。 关于第二个问题:这是一个更好的做法,一个接一个地命名函数,并在代码中使用这些名称,而不是像往常一样定义它。 在某些情况下,它会减less内存消耗。