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

Redis和Node.js以及Socket.io问题,node.js,redis,Node.js,Redis,我刚刚学习了redis和node.js,有两个问题我没有找到满意的答案 我的第一个问题是关于在node.js中重用redis客户机。我找到了这个问题和答案:,但这还不够让我满意 现在,如果我在connection事件中创建redis客户端,它将为每个连接生成。所以,如果我有20k个并发用户,那么就会有20k个redis客户端 如果我把它放在连接事件之外,它将只生成一次 答案是,他在连接事件之外为每个函数创建了三个客户端 然而,据我所知,当编写生成子进程并并行运行的应用程序时,需要在创建子实例的函

我刚刚学习了redis和node.js,有两个问题我没有找到满意的答案

我的第一个问题是关于在node.js中重用redis客户机。我找到了这个问题和答案:,但这还不够让我满意

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

如果我把它放在连接事件之外,它将只生成一次

答案是,他在连接事件之外为每个函数创建了三个客户端

然而,据我所知,当编写生成子进程并并行运行的应用程序时,需要在创建子实例的函数中创建MySQL客户端。如果您在它之外创建它,MySQL将给出一个错误“MySQL服务器已经离开”,因为子进程将尝试使用相同的连接。它应该分别为每个子进程创建

所以,即使你为每个函数创建了三个不同的redis客户端,如果你有30000个并发用户同时发送2k条消息,你也会遇到同样的问题,对吗?因此,每个“用户”都应该在连接事件中拥有自己的redis客户端。我说得对吗?如果不是,node.js或redis如何处理并发请求,与MySQL不同?如果它有自己的机制,并且在redis客户端中创建类似子进程的东西,那么为什么我们需要创建三个不同的redis客户端呢?一个就够了

我希望问题是清楚的

--更新--

我已经找到了以下问题的答案。 不需要回答,但我的第一个问题仍然有效

--更新--

我的第二个问题是。我也不太擅长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
                }
            });
        }
    });
});
因此,如果我学习正确,如果我需要等待I/O应答,我需要运行函数中的每个函数。否则,node.js的非阻塞机制将允许第一个函数运行,在这种情况下,它将并行地获得结果,但如果第二个函数需要时间才能获得结果,那么它可能没有结果。因此,如果您从redis获取一个结果,并且您将在第二个函数中使用该结果,那么您必须将其封装在redis get函数中。否则,第二个函数将运行而不会得到结果

因此,在本例中,如果我需要运行7个不同的函数和8个。函数将需要它们的结果,我需要这样递归地编写它们吗?还是我遗漏了什么

我希望这也很清楚

非常感谢

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

事实上,你不是:)

问题是node.js与PHP非常不同。node.js不会在新连接上生成子进程,这是它可以轻松处理大量并发连接的主要原因之一,包括长期存在的连接(Comet、Websockets等)。node.js使用单个进程中的事件队列顺序处理事件。如果您想使用多个进程来利用多核服务器或多台服务器,则必须手动执行(但如何执行超出了本问题的范围)

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

因此,每个“用户”都应该在系统中拥有自己的redis客户端 连接事件。我说得对吗

您不应该为每个连接的用户创建一个新的Redis客户端,这不是正确的方法。相反,只需最多创建2-3个客户端并使用它们

有关更多信息,请查看此问题:

关于第一个问题: “正确的答案”可能会让你认为你擅长一种连接。 实际上,每当您在做等待IO、计时器等的事情时,实际上是让节点在队列上运行等待方法。因此,如果您只使用一个连接,您实际上会将您所处理的线程(单个CPU)的性能限制在redis的速度范围内-这可能是每秒数百次回调(非redis等待回调仍将继续)-虽然这不是性能差,但没有理由创建这种限制。建议创建几个(5-10个)连接,以避免整个过程中出现此问题。对于较慢的数据库(例如MySQL),这个数字会上升,但取决于查询类型和代码细节

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

顺便说一句,要完成对第二个问题的回答,您还可以查看流控制库“异步”和“步骤”。