持久的数据库连接——是还是否?

Posted

技术标签:

【中文标题】持久的数据库连接——是还是否?【英文标题】:Persistent DB Connections - Yea or Nay?持久的数据库连接——是还是不是? 【发布时间】:2010-09-08 04:42:33 【问题描述】:

我在项目中使用 php 的 PDO 层进行数据访问,我一直在阅读它,发现它对持久数据库连接具有良好的先天支持。我想知道何时/是否应该使用它们。我会在重 CRUD 的应用程序中看到性能优势吗?是否有缺点需要考虑,可能与安全性有关?

如果这对你很重要,我使用的是 mysql 5.x。

【问题讨论】:

【参考方案1】:

简而言之,我的经验表明应尽可能避免持久连接。

请注意,mysql_close 是使用 mysql_pconnect 创建的连接的无操作 (no-op)。这意味着客户端不能随意关闭持久连接。当连接上的任何活动持续时间超过 wait_timeout 时,mysqldb 服务器将关闭此类连接。如果 wait_timeout 值很大(比如 30 分钟),那么 mysql 数据库服务器可以轻松达到 ma​​x_connections 限制。在这种情况下,mysql db 将不会接受任何未来的连接请求。 这是您的寻呼机开始发出哔哔声的时候。

为了避免达到 ma​​x_connections 限制,使用持久连接需要仔细平衡以下变量...

    一台主机上的 apache 进程数 运行 apache 的主机总数 mysql 数据库服务器中的wait_timout 变量 mysql 数据库服务器中的 max_connections 变量 一个 apache 进程在重新生成之前服务的请求数

所以,经过充分考虑,请使用持久连接。您可能不想为了从持久连接中获得的微薄收益而引发复杂的运行时问题。

【讨论】:

“mysql_close 是使用 mysql_pconnect 创建的连接的无操作 (no-op)”所需的引用。对于 mysqli,它肯定不是空操作:php.net/manual/en/mysqli.persistconns.php【参考方案2】:

您可以将其用作粗略的“规则集”:

,使用持久连接,如果:

只有少数应用程序/用户访问数据库,即您不会导致 200 个打开(但可能是空闲)连接,因为在同一主机上共享了 200 个不同的用户。 数据库正在您通过网络访问的另一台服务器上运行 一个(一个)应用程序非常频繁地访问数据库

,不要使用持久连接,如果:

您的应用程序只需每小时访问数据库 100 次。 您有许多网络服务器访问一个数据库服务器 您在 prefork 模式下使用 Apache。它为每个子进程使用一个连接,这可以相当快地增加。 (通过 cmets 中的@Powerlord)

使用持久连接的速度要快得多,尤其是当您通过网络访问数据库时。如果数据库在同一台机器上运行并没有太大区别,但它仍然快一点。然而 - 正如名字所说 - 连接是持久的,即它保持打开状态,即使它没有被使用。

问题在于,在“默认配置”中,MySQL 只允许 1000 个并行“开放通道”。之后,拒绝新连接(您可以调整此设置)。因此,如果您有 - 比方说 - 20 台 Web 服务器,每台服务器上有 100 个客户端,并且每个服务器每小时只有一个页面访问权限,那么简单的数学将告诉您,您需要 2000 个与数据库的并行连接。那是行不通的。

Ergo:仅用于请求较多的应用程序。

【讨论】:

另外,如果您在 prefork 模式下使用 Apache,请不要使用持久连接。它为每个子进程使用一个连接,这可以相当快地增加。 @BlaM,我没有收到你的最后一段。持久连接不允许您重用它们(这就是重点吗?)所以您不需要 2000 个连接,因为它们将被重用?或者你的意思是每个客户都有一个唯一的用户名?即便如此,旧的持久连接不会在完成后自动关闭,为新连接让路吗? @Pacerier:我的意思是每个客户端都有自己的用户名。在这种情况下,旧连接将 关闭以使新连接成为可能,因为允许连接的 limit 由 MySQL 管理,而连接的持久性由 PHP 端管理 -所以从 PHP 的角度来看,数据库只是不允许连接。它不知道已达到限制并且关闭旧连接会有所帮助。 @BlaM,嗯,你是说默认的C libmysql也有这个问题?至于PHP,这似乎是一个需要在PHP端修复的错误。 PHP端应该向服务器查询最大值,如果达到最大值则释放它的LRU。 我没用过C mysql库,所以不知道。但是我不认为客户端(PHP 或 C)可以在完全自动化方面做很多事情。我不确定是否有允许手动配置的 PHP.INI 设置,但是一旦情况变得更加复杂,全自动解决方案可能会开始变得不可预测(例如,不仅仅是一个客户端/网络服务器访问一个数据库服务器) .【参考方案3】:

一般来说,有时您需要使用非持久连接,最好将单一模式应用于数据库连接设计(只要在您的上下文中使用持久连接的好处相对较小。)

【讨论】:

【参考方案4】:

我打算问同样的问题,但我不会再次问同样的问题,我只是添加一些我找到的信息。

Are PHP persistent connections evil ? Persistent Database Connections

还值得注意的是,较新的 mysqli 扩展甚至不包括使用持久数据库连接的选项。

我目前仍在使用持久连接,但计划在不久的将来切换到非持久连接。

【讨论】:

这应该是评论而不是答案。【参考方案5】:

以我的拙见:

当使用 PHP 进行 Web 开发时,您的大部分连接将仅在页面执行的生命周期内“有效”。持久连接将花费您大量开销,因为您必须将其放入会话或类似的东西中。

在页面执行结束时断开的单个非持久连接在 99% 的情况下都可以正常工作。

另外 1% 的时间,您可能不应该在应用程序中使用 PHP,并且没有适合您的完美解决方案。

【讨论】:

【参考方案6】:

IMO,这个问题的真正答案是最适合您的应用程序。我建议您使用持久连接和非持久连接对您的应用程序进行基准测试。

Maggie Nelson @@Objectively Oriented 在 8 月发布了有关此问题的信息,Robert Swarthout 发布了附带的帖子,其中包含一些硬数字。这两本书都不错。

【讨论】:

“客观导向”链接已失效。 我不喜欢这个答案,因为基准测试通常以非常不准确的方式完成。如果您的计算机以“不同于现实世界的访问模式”(这是典型的测试)访问它,它看起来会非常好。时机非常重要,就像现实生活中经常发生的其他几种“难以复制”的情况一样。我建议仔细考虑并避免它,除非你肯定需要它。预优化是第一罪。【参考方案7】:

创建与数据库的连接是一项相当昂贵的操作。持久连接是个好主意。在 ASP.Net 和 Java 世界中,我们有“连接池”,这大致相同,也是一个好主意。

【讨论】:

以上是关于持久的数据库连接——是还是否?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 Doctrine 与持久 PDO 连接一起使用?

[日常] MySQL数据库持久连接

持久数据库连接 - 是或否?

如何使用持久性动态配置数据库连接

lvs持久连接

与没有 GCM 的推送服务器的持久 http 连接