【问题标题】:Knex.js default max pool leads to Error: ER_CON_COUNT_ERROR: Too many connectionsKnex.js 默认最大池导致错误:ER_CON_COUNT_ERROR: Too many connections
【发布时间】:2020-06-27 05:16:36
【问题描述】:

我们有 30 个 DigitalOcean 液滴,每个液滴用于 Web CRM 用户,它们与 knex.js 共享同一个 MySQL 数据库。 由于很少有其他用户,我们会收到错误:

  • “ER_CON_COUNT_ERROR:连接太多”
  • “Knex:获取连接超时。池可能已满。是否缺少 .transacting(trx) 调用?”
  • “数据包乱序。得到:1 预期:0”

MySQL 托管在具有 4Gb RAM 的单独服务器上,并且有大量可用 RAM 和 CPU(超过 50%)。

在我们的 nodejs 应用程序 knex 中引用为单例:

const knex = require('knex')({
    client: 'mysql',
    connection: {
        host: mySqlHost,
        user: mySqlUser,
        password: mySqlPass,
        database: mySqlDb
    }
})
module.exports = {
    knex
};

那么,为什么即使我们的 MySQL 的默认最大连接数为 150 个,也可能达到连接数限制(因为我们谈论的是 30 个用户,他们进行了相当多的读写操作,但毕竟是 30 个用户)?!

根据http://knexjs.org/#Installation-client“对于 MySQL 和 PG 库,连接池的默认设置为最小值:2,最大值:10” - 将其增加到 50 是否安全? Knex 文档没有很好地解释他们的池概念,而是引用https://github.com/vincit/tarn.js 以获得“更多详细信息”,并且没有关于 MySQL 的任何详细信息。

非常感谢任何帮助。

附言我们意识到共享数据库会导致性能问题,但我们正在考虑在达到数千名用户时迁移它,并且从常识来看,这是我们对 MySQL 的期望。现在我们遇到了超过 30 个用户的性能问题。

【问题讨论】:

    标签: mysql sql node.js knex.js


    【解决方案1】:

    我在 Cloud Run 上遇到过同样的问题。 在数据库用完限制为 1000 的连接之前,我几乎没有达到 50req/s

    到目前为止,最好的性能是当我为每个实例设置以下池设置时:

    {
      min: 0,
      max: 40,
      destroyTimeoutMillis: 100,
      idleTimeoutMillis: 100,
      reapIntervalMillis: 100,
      createRetryIntervalMillis: 400,
      acquireTimeoutMillis: 10000,
      createTimeoutMillis: 10000
    }
    

    我发现这些设置非常糟糕,因为理想情况下应该更频繁地使用现有连接,但 knex/tarn 似乎没有正确使用它们?

    还有其他人解决过这个类似的问题吗?

    【讨论】:

      【解决方案2】:

      我们有 30 个 DigitalOcean 液滴,每个液滴用于 Web CRM 用户,它们与 knex.js 共享同一个 MySQL 数据库。由于很少有其他用户,我们会收到错误:

      如果我从这里正确理解 https://www.digitalocean.com/products/droplets/ 是单独的虚拟服务器。因此,如果您正在运行 30 个单独的节点进程来初始化“相同”的 knex 实例,那么您实际上无法在它们之间共享相同的单例 knex 实例。每个节点进程都会初始化它自己的副本。

      因此,当您创建了 30 个 knex 实例并且默认情况下 knex 使用池大小 10 进行初始化时,最多尝试创建 300 个到数据库的连接。

      根据http://knexjs.org/#Installation-client“对于 MySQL 和 PG 库,连接池的默认设置为最小值:2,最大值:10” - 将其增加到 50 是否安全?! Knex 文档没有很好地解释他们的池概念,而是引用https://github.com/vincit/tarn.js 获取“更多详细信息”,并且没有关于 MySQL 的任何详细信息。

      没有什么要说明的 MySQL,也没有理由让 knex 复制 tarn.js 库(也不是 mysql 数据库/驱动程序)的文档。

      将其增加到您的数据库配置允许的任何数字是安全的。尽管在您的情况下,如果您运行 30 个 knex 实例,则最大连接数应该比数据库硬限制少 30 倍。

      处理连接同一个数据库的多个 knex 进程有点复杂,我会考虑将 mysql 服务器的连接限制提高到 500 或其他东西,以便它能够为你的 30 个 droplet 提供服务,每个 droplet 最多可以使用 10 个连接。

      附言我们意识到共享数据库会导致性能问题,但我们正在考虑在达到数千名用户时迁移它,并且从常识来看,这是我们对 MySQL 的期望。现在我们遇到了超过 30 个用户的性能问题^

      共享同一个数据库可能会也可能不会导致性能问题...这完全取决于对数据库进行的查询类型。

      【讨论】:

        猜你喜欢
        • 2015-06-09
        • 2020-04-25
        • 2014-10-14
        • 1970-01-01
        • 2022-10-05
        • 2016-01-15
        • 1970-01-01
        • 2013-07-24
        • 2011-07-15
        相关资源
        最近更新 更多