【问题标题】:How to handle too many concurrent connections even after using a connection pool?即使在使用连接池后如何处理过多的并发连接?
【发布时间】:2015-10-10 02:53:25
【问题描述】:

场景

假设您的网站或应用拥有大量流量。即使使用数据库连接池,性能也会受到影响(站点/应用程序甚至可能崩溃),因为并发连接太多。

问题

处理这个问题的方法是什么?

我的想法

我在想有这个问题的人可以创建多个数据库(可能在不同的机器上,尽管我不确定是否有必要),每个数据库都具有相同的信息并同时更新,这将授予原始数量的倍数单个数据库的连接数。但如果数据库很大,这似乎不是一个非常可行的解决方案。

【问题讨论】:

  • 问题太模糊了……服务器的部署是什么?
  • 取决于,但是当分析显示检索到相似/相同的数据时,本地缓存可以创造奇迹,因为您取出了整个 db-roundtrip。
  • 我认为这个问题太模糊了,恕我直言异步网络框架(或您的应用程序的类似库)是您正在寻找的朋友。
  • 我故意让这个问题含糊不清,因为我不想要一个依赖于特定设置的答案。我想要一个高水平的答案,为我指明正确的方向,而这正是我得到的。

标签: mysql database postgresql concurrency database-connection


【解决方案1】:

如果您还没有这样做,您可以尝试在应用服务器上运行您的应用程序——在您的应用程序后面获取一些中间件。大多数应用程序服务器都会做自己的连接池(因为从 Web 应用程序到数据库连接池的连接仍然非常昂贵)。此外,您应该能够将应用程序服务器配置为使用共享连接——顾名思义,这将允许尽可能共享连接。

简而言之,使用应用服务器。如果您已经是,请提及您正在使用哪一个,我们可以从那里优化服务器配置。

【讨论】:

    【解决方案2】:

    对于这个问题,您应该调查很多事情。
    - 有多少同时连接。您始终可以增加 ram 并增加最大连接数。 MySQL 可以支持数百万个连接。

    -确保您的应用正在关闭连接。即使有一个池,应用程序也必须将连接返回到池。

    -在单独的服务器上运行数据库。

    -确保您已优化查询。一个长时间运行的查询可能会减慢系统速度。

    -如果其他方法失败,最后使用 MySQL 集群。对于高流量站点,您可能需要考虑这一点以避免单点故障。

    【讨论】:

      【解决方案3】:

      这是一个典型的应用程序扩展问题,并且已经设计了许多解决方案 - 例如 Google Big Table 和 Amazon Elastic 产品。 如果迁移到云中并利用它们都提供的自动缩放选项不是一种选择,那么您需要创建自己的设置。查看PostgresMySQL 的文档,您会发现它们的想法非常相似,包括

      • 分片:将您的客户端数据分散到多个数据库中,并将客户端请求路由到正确的数据库实例。

      • 负载平衡:将您的应用程序部署在多台服务器上,并使用中间件根据服务器上的负载路由请求。它需要某种数据库同步工具,例如SymmetricDS,以保持数据库同步。

      这绝不是对所有选项的全面概述,但可能会帮助您入门。

      【讨论】:

        【解决方案4】:

        词干不够具体,无法给出明确的建议,但可以做的完整列表如下:

        • 数据库集群:适用于你不想改变你的应用层和数据库就是你所接触的情况。您可以从数据库集群中获得多少是有限度的。如果您的请求量不断增长,此解决方案最终也会失败。但好消息是,您已经拥有了普通单实例 MySQL 中已有的所有功能。
        • Sharding:由于你的问题是用 MySQL 标记的,并且它本身不支持分片,如果你想使用这个解决方案,你需要在你的应用层实现它。在此解决方案中,您将在逻辑上将数据分散在多个数据库中(最好在不同硬件上的多个 MySQL 实例中)。您有责任找到保存您指定数据的适当数据库。这是有史以来最有效的解决方案之一,但并不总是可行的。它最大的缺陷是分散在两个或多个数据库中的数据不能包含在一个事务中。
        • 复制:根据您的方案,您可能能够合并数据库复制并在其上保存数据副本。通过这种方式,您可以连接到它们而不是主数据库并减少它的负载。默认的复制定义是主/从场景,其中数据流是一种方式,从主到从。因此,您可能在从属设备上进行的更改将应用​​于从属设备,它们不会影响主设备。但也有一个主/主复制配置,其中数据流是双向的。然而,您不能假设两个主服务器之间并发数据更改的原子完整性。最后,如果您计划在主/从模式下使用该解决方案并使用从属设备进行只读访问,则此解决方案最为有效。
        • 缓存:也许这个解决方案不应该包含在这里,但是因为你的词干不拒绝它,所以它就在这里。减少数据库负载的方法之一是在提取数据后对其进行缓存。如果提取数据成本高昂,此解决方案可能特别有用。那里有许多缓存服务器,例如memcachedredis。通过这种方式,您可以省略很多数据库连接,但仅用于提取数据。
        • 其他存储引擎:如果您当前的引擎无法满足您的需求,您可以随时切换到性能更高的引擎。当然,这只有在您的需求允许时才可行。现在有 NoSQL 引擎,比 RDBMS 性能要好得多,它原生支持分片,你可以用最小的努力线性扩展它们。还有一些基于 Lucene 的解决方案,具有强大的全文搜索功能,为您提供相同的自动分片。事实上,您应该使用传统 RDBMS 的唯一原因是事务的原子行为。但如果事务不是必须的,还有比 RDBMS 更好的解决方案。

        【讨论】:

          【解决方案5】:

          复制 -- 主加任意数量的从属。这为您提供了“无限”读取缩放。

          断开连接 -- 连接不应使连接保持打开的时间过长。

          Unix,而不是 Windows -- 需要我详细说明吗?

          InnoDB -- 使用 InnoDB,而不是 MyISAM。

          SlowLog -- 将 long_query_time 设置为 1 并注意前几个查询;优化它们。请参阅 pt-query-digest 以获取有关总结慢日志的帮助。

          【讨论】:

            【解决方案6】:

            我遇到了类似的问题,即使应用程序应该关闭它的连接,我也可以看到它们在 SQL 中作为睡眠连接堆积起来。检查问题后,我将以下内容添加到 webconfig 中的连接字符串中,并使用以下内容进行测试:

            Connection Lifetime=600
            

            这应该会在 10 分钟后终止所有休眠连接 - 但它没有...

            经过进一步审查,我的 Web 服务器和 SQL 服务器都有待处理的 Windows 更新。神奇的是,问题消失了!

            我希望我可以为您提供更具体的答案,但介于添加“连接生命周期”和使用补丁更新我的 Web 和 SQL 服务器之间的某个地方完全消除了我的问题。我已经干净了 3 周了,没有任何问题。

            【讨论】:

              【解决方案7】:

              在我们的例子中,当 mysql 并发连接数达到 100 时,我们也面临同样的问题。

              最后,我们找到了一个很棒的 npm express-myconnection 模块 (https://www.npmjs.com/package/express-myconnection)。完成后它会自动释放连接。它支持SinglePool连接策略。

              它工作正常。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-02-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-07-29
                • 1970-01-01
                • 2015-06-18
                • 2017-10-26
                相关资源
                最近更新 更多