PDO 持久连接缓存要求

Posted

技术标签:

【中文标题】PDO 持久连接缓存要求【英文标题】:PDO persistent connections cache requirement 【发布时间】:2013-10-24 04:55:05 【问题描述】:

确保我正在编写一个方案以最大限度地减少与我的 mysql 数据库的连接数的最佳方法是什么?

目前,我的服务器上有一个 ubuntu / php / apache 设置,我正在使用以下代码和 PDO 来确保持久连接:

$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
    PDO::ATTR_PERSISTENT => true
));

但是,我似乎始终有 10 个或更多连接。我不确定这是为什么。引用php.net:

许多网络应用程序都将从建立持久连接中受益 到数据库服务器。持久连接最后没有关闭 脚本,但在另一个脚本请求时被缓存并重新使用 使用相同凭据的连接。持久连接 缓存允许您避免建立新的开销 每次脚本需要与数据库通信时连接,导致 在更快的网络应用程序中。

这是否意味着我必须写 $dbh = null “关闭”并缓存连接?

【问题讨论】:

第一件事:为什么要“最小化连接数”? 我的网站上似乎只有几个用户,我的服务器连接数已达到最大。我想将我的网站扩展到可能有数千人,这是否意味着我需要数万个连接才能成为我的极限?考虑到每个访问该网站的人可能会因为打开多个标签而产生 5-10 个连接。 对于一个常规站点,一个连接就足够 10 个用户使用了。甚至他们每个人都打开了 5 个标签。你知道 PHP 是如何工作的吗? 我不知道 PDO 如何处理连接。我只知道我的网站不会产生太多流量,但建立了很多连接。我正在寻找解决我遇到的问题的方法,而不是居高临下的问题没有任何帮助。 另外,我实际上是从这个线程中的评论中得到了这条信息:@bvpx: The number of connections will depend on how many PHP scripts you expect to be running simultaneously at any given time. I, for example, often click to open a number of pages in different tabs all at once. So, as one user, I could consume maybe 5 database connections. If all users are simultaneously connected to the site (and actively using it), you can hazard your own guess as to the resources required. – eggyal 55 mins ago 【参考方案1】:

根据定义,持久连接是未关闭的连接(即它持久);好处是 PHP 保持连接 到数据库以供其他脚本使用(即,每次脚本运行时,它都不需要拆除和设置新的数据库连接)。

不必写$dbh = null,因为这实际上暗示了脚本执行的终止;但是,如果您想在脚本结束之前表明您已完成连接,您可以显式编写它(然后,PHP 的垃圾收集器将在某个时候释放资源并将其返回到连接池以供其他使用脚本的使用)。

如果您希望在每个脚本结束时关闭并销毁连接,请不要使用持久连接!

【讨论】:

@StBlade 不,不是。查看我的答案/链接,了解原因。 @StBlade:可以想象持久连接可能会暴露一些安全问题:例如一个脚本设置特定的数据库状态,然后在不取消设置该状态的情况下终止(可能出乎意料);下一个使用该连接的脚本将处于它没有预料到的状态。例如,第一个连接可能会更改会话时区;然后第二个连接可能会测试以查看当前是否允许登录。此类问题始终可以通过在执行数据库操作之前验证数据库状态的第二个脚本来解决。 @eggyal - 尽管不太可能,但是否有可能即使经过验证也可能出现意外状态?这会发生在双核机器中,例如,两条语句并行运行,并且第二个连接中的位翻转发生在验证之后但在第一个连接中状态更改之前? @bvpx:一个连接不能同时被多个脚本使用;当脚本尝试“连接”到 MySQL 时,它会从池中分配给脚本,然后在脚本释放它时(显式或隐式)返回到池中。 @bvpx:即使没有持久连接,这类问题也存在,属于事务隔离领域。【参考方案2】:

“我似乎还有 10 个连接”似乎不是一个合理的问题或担忧,因为只要 PHP 正在运行,该属性将只保存数据库资源对象。因此,正如@eggyal 所说,如果您希望连接关闭或销毁,请不要使用持久连接。

另请阅读:

What are the disadvantages of using persistent connection in PDO Why You Should Use Persistent Connections with MySQL

【讨论】:

当我的连接数超过 30 时,我收到一个关于连接过多的错误,因此每天在我的网站上拥有 10 个连接可能有 4 个唯一用户对可扩展性有点担心。除非两者无关。 @bvpx:如Too many connections 中所述,您可以通过设置max_connections 来调整允许的最大连接数:您似乎正在使用低成本的托管包,它限制了根据您的服务级别的连接数。如果您需要您的应用程序扩展超出您的托管包支持的范围,那么您可能需要升级您的托管包。 最后一个问题,谢谢大家:这么少的用户有10+个数据库连接正常吗?我听说有“更好的方法”来管理连接,也许我在 PHP 脚本的某个地方犯了一个新手错误? 好吧,我们无法在不知道您的 php 代码是什么样子的情况下进行咨询。如果你按照 DRY 等原则以非常优化和高效的方式创建了脚本,那么我猜你没问题,否则就不行 @bvpx:连接数取决于您希望在任何给定时间同时运行的 PHP 脚本数量。例如,我经常单击以同时打开不同选项卡中的多个页面。因此,作为一个用户,我可能会消耗 5 个数据库连接。如果所有用户都同时连接到该站点(并积极使用它),您可以自行猜测所需的资源。

以上是关于PDO 持久连接缓存要求的主要内容,如果未能解决你的问题,请参考以下文章

PHP & PDO - 有啥方法可以建立“安全”的持久连接吗?

PHP PDO,连接持久时无法设置名称?

mysqli 持久连接

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

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

在mysql中使用持久连接的目的和好处是啥?