如何在nodejs/express中(重新)使用redis客户端连接?

7
给定一个简单的例子:
var express = require("express")
var redis = require('redis')
var app = express()

var client = redis.createClient()

app.get('/', function(req, res) {
    req.connection.setTimeout(2 * 1000)
    client.set("test", 1, function (err, resp) {
        res.send('Hello World')
    })
})

app.listen(80)

Redis连接不需要为每个请求重新建立,对吗?

你需要使用Redis连接池吗?

3个回答

9

回复incarnate关于连接池的帖子:

你好 - 首先澄清一下,Redis服务器确实是单线程的。

您在使用异步方式时看到的命令排序是一种人为制造的现象,并且与node_redis库或Redis本身无关。

在node_redis中使用连接池绝对不是必需的。您当然可以使用它,但不建议这样做。连接池会降低Redis流水线操作的效率,并且由于Redis协议的状态性质,可能会在某些命令上出现问题。

原因#1:我不确定这是否重要,或者通过创建额外的客户端来增加GC负担可能更糟。

原因#2:实际情况并非如此。 Redis服务器是单线程的。如果您在等待服务器,则所有客户端都在等待服务器。如果您在JavaScript中被阻止,则该进程中的所有客户端都在JavaScript中被阻止。

原因#3:node_redis库已经在故障后重新连接。


感谢您详细的解释。我肯定错过了一个关键点,那就是Redis确实是单线程的。再次感谢! - BorisOkunskiy

4

对于您的服务器,只需要一个连接到Redis,并且只有在服务器停止时才需要关闭它。您的服务器仅作为单个进程运行。


8
如果你使用发布/订阅通道,这是错误的。如果你的连接建立原子操作的监视器也是错误的。不要这样做。 - Eric Rini
处理每分钟5万个请求的服务器,且每个请求至少执行2个Redis操作(GET/SET),这个方法是否适用?单个Redis连接是否足够? - Ayaz Pasha
@AyazPasha 使用"redis-benchmark"命令与您将使用的操作一起使用,例如: redis-benchmark -t ping,set,get -n 50000 - mzalazar

1

你不需要在每个请求上打开和关闭连接。

在您的示例中,即使请求是异步处理的,回调也始终会在正确的上下文中执行。 但是您应该小心非原子事务,因为它们可能会破坏您的数据库。使用MULTI命令来注意这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接