如何使用连接池后如何处理太多并发连接?

时间:2015-07-20 20:26:39

标签: mysql database postgresql concurrency database-connection

方案

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

问题

处理此问题的人有哪些选择?

我的想法

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

7 个答案:

答案 0 :(得分:10)

词干的具体程度不足以给出一个坚定的建议,但可以做的完整列表如下:

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

答案 1 :(得分:3)

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

简而言之,请使用appserver。如果你已经有,可以提一下你正在使用哪一个,我们可以从那里看看优化服务器配置。

答案 2 :(得分:3)

复制 - Master加上任意数量的slave。这让你无限制地#34;读取缩放。

断开连接 - 连接不应使连接打开的时间超过必要的时间。

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

InnoDB - 使用InnoDB,而不是MyISAM。

SlowLog - 将long_query_time设置为1并观察前几个查询;优化它们。有关汇总slowlog的帮助,请参阅pt-query-digest

答案 3 :(得分:2)

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

的概念
  • 分片:将客户端数据传播到多个数据库,并将客户端请求路由到正确的数据库实例。

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

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

答案 4 :(得分:0)

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

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

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

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

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

答案 5 :(得分:0)

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

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

工作正常。

答案 6 :(得分:-1)

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

Connection Lifetime=600

这应该在10分钟后杀死任何睡眠连接 - 但它没有......

在进一步审核时,我的Web服务器和SQL服务器上都有挂起的Windows更新。奇迹般地,问题消失了!

我希望我能为您提供更具体的答案,但在添加“连接生命周期”和让我的网络和SQL服务器更新补丁之间的某个地方完全消除了我的问题。我现在已经干净了3个星期,没有问题。