Node.js + MySQL:什么时候使用连接池?

4
首先,我知道有几个类似的问题,但它们没有回答我所需要的内容,所以让我开一个新的问题 :)
其次,这个问题是关注mysql的,但不仅限于它,也适用于其他可池化服务,比如memcached。
据我所知,nodejs单线程执行脚本,但它可以创建线程,因此能够管理服务器中的并发用户。这就是为什么创建连接池是有意义的。
问题在于,当我有一个由express提供的测试API,并执行以下基准代码时:
ab -t 30 -c 1000 localhost/test

给我单向连接到数据库的以下输出:
Requests per second: 1732.07 [#/sec] (mean)
Time per request: 577.344 [ms] (mean)

在只有1个连接的mysql池中:
Requests per second: 1346.24 [#/sec] (mean)
Time per request: 742.811 [ms] (mean)

使用一个有100个连接的连接池:

Requests per second: 662.82 [#/sec] (mean)
Time per request: 1508.716 [ms] (mean)

这应该是相反的,不是吗?使用池化连接可以获得更好的性能。

我知道池化管理需要时间(但不应该很长),sql查询非常简单,但是...我不知道...

API大概像这样:

function test(response, request, dbc) {
  dbc.query(SQL, PARAMS, (err, rows) => {
    dbc.release();
    if(err) {
      log.error('Error while performing the query', err.code);
      return;
    }

    response.send(response, rows);
  });
}

在这里,dbc是单个/池化连接的抽象数据库连接,并且dbc.release()如果连接不是来自池,则不执行任何操作(允许使用相同的代码在直接/池化连接上工作,只需更改选项)。

我是否漏掉了什么?

2个回答

0

只是要更正一点:Node.js 在单个线程中运行非阻塞 I/O 操作,这使它能够同时处理多个请求(交错)-因此无需使用线程来为多个用户提供服务。

使用池的长响应时间似乎有些奇怪,我必须承认。但是测试也相当简单 - 发送一个查询并关闭连接。我想如果测试在释放连接之前执行了一些“工作”,那么池化会开始变得更好。通常会打开事务,执行多个语句等等。您可以使用简单的延迟(例如2秒)模拟这个过程,然后再释放连接。

您可以阅读更多关于如何从单个线程运行 Node 服务器请求的信息,例如 "Node.js: 100 new requests while still serving the first one!"


是的,我说查询非常简单,也许这就是问题所在...但是性能差异(3倍)仍然太大了。这很奇怪... - danikaze

0

好的,我认为你在每次请求时创建单个连接时出错了。使用单个连接更快,因为在执行查询之前只需打开一次网络连接,而使用池化连接进行相同操作时,必须打开100个连接才能开始执行查询。基本上,在池化连接中,它必须获取100个连接才能执行任何操作,而在单个连接中,它只需要获取一个连接。现在,如果您正在使用连接池,则每次请求结束时关闭连接是没有意义的。连接池的整个目的是重用连接,以便您不必每次都进行网络跳转以打开新连接,从而减少延迟并避免在每个请求上进行网络握手。


2
不行。第一,当使用直接连接时,连接是在服务器创建时(或断开连接时)打开的,而不是在请求到来时打开的。因此,它的行为类似于一个持久连接。第二,池中的100个连接也是在服务器创建时创建的,而不是在请求到来时创建的(测试函数中没有关于创建/删除连接的内容,只有释放池中的连接)。 - danikaze

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