PHP-> Mysql持久连接池,没有mysql_pconnect-可能吗?


12

一段时间以来,我一直在试图找到一种不错的方法。但是很难找到合适的方法来做到这一点。我猜这一定有可能。

简单来说,这就是我要完成的工作:

PHP / Other front end -> [SOCKET] ->

Locally hosted 'pooler' -> [Pool of persistent TCP/IP connection(s)]->

Externally hosted MySQLD

是否存在这种工具/做事方式?

我们基本上想在不使用mysql_pconnect的情况下实现持久的mysql连接。

我诚恳地要求我们不要开始讨论如何不需要持久性连接等等。我们已经用完TIME_WAIT端口,并且遇到其他问题,如果实施这种类型的系统,则可以解决。

是的,总结一下……我们将实现一个基于本地端的Socket的mysql连接池,并持久化与(LAN)外部托管的mysql服务器的连接。

我们不使用事务或任何其他将受到回收的mysql连接影响的事务。

我们在前端使用master + master percona 5.5集群运行linux。

谢谢!

Answers:


12

经过大量的搜索,我终于找到了解决方案。

我不是一个作家,所以我会尽力使它尽可能简洁。

据我所知,有两种可能的解决方案:

SQL中继

http://sqlrelay.sourceforge.net/

这正是问题所要求的,甚至更多。我不会详细介绍我能够找到的内容,但是会提到这不是可行的解决方案,因为它不透明。含义流程如下:

PHP -> Queries -> SQL Relay Extension -> SQL Relay -> Externally hosted MySQL

因此,这将涉及将我们所有的代码从mysql重写为sql relay。在我们的情况下不是一个选择。

话虽如此,如果有人正在计划一个新的大型项目,而该项目需要SQL Relay具有的众多功能中的任何一个,那么听起来就很美。

MySQL代理

http://forge.mysql.com/wiki/MySQL_Proxy

这就是我们最终使用的解决方案。

做到这一点的关键是执行MySQL代理的池化LUA脚本。

可以在以下位置找到该LUA扩展:

https://github.com/cwarden/mysql-proxy/blob/315ab806bb95b8223f5afd3d238eff2a40af03d8/lib/ro-pooling.lua

无需赘述,这里是一些基本统计信息...切记,这是在较低的使用时间下进行测试的:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
   6433   38598  572537

切换到mysql-proxy之后,解决问题:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
     32     192    2848

您可以清楚地看到,MySQL的TIME_WAIT端口几乎已消失。

现在,连接实际上是持久的,无需使用mysql_pconnect / mysqli_connect(... p:hostname ...)。

值得一提的是,pooler lua脚本顶部附近似乎有一些可配置的设置。

本地min_idle_connections

本地max_idle_connections

这些似乎很容易解释。除外:似乎每个用户名(和密码?未经测试...很可能不是这样)的组合都会创建自己的一组持久连接。

因此,将max_idle_connections乘以将要连接到数据库的唯一mysql用户数。这应该使您了解最终将拥有多少个空闲连接。

因此,让我重申一下,这个简短的内容会为通过Google搜索的用户找到一些关键字:

当使用PHP时,可以在没有mysql_pconnect的情况下保持持久的mysql连接吗?

是的,如果您不介意重建大多数代码以通过其扩展名将查询通过管道传递,或者通过使用带有ro-pooling.lua脚本的mysql-proxy透明地进行此操作,则可以通过SQL Relay完成。

大约一年以来,我们一直想要这样的东西。

请享用!


为什么不简单地使用mysqli的持久性函数提供的清除功能(如下面的回答所述)?如果您无权访问mysqli,为什么不简单地使用mysql_pconnect一些“清理功能”来启动每个连接?
起搏器

4
  1. mysqli扩展的PHP 5.3中引入了持久连接支持。支持已存在于PDO MYSQL和ext / mysql中。持久连接背后的想法是,客户端进程和数据库之间的连接可以被客户端进程重用,而不是被多次创建和销毁。这样可以减少每次需要时都需要创建新连接的开销,因为未使用的连接会被缓存并准备重用。

  2. 与mysql扩展不同,mysqli它不提供单独的函数来打开持久连接。要打开持久连接,连接时必须在主机名前加p:。

  3. 持久连接的问题在于客户端可能会将它们置于不可预测的状态。例如,在客户端意外终止之前,可能已激活了表锁。重新使用此持久连接的新客户端进程将“按原样”获得连接。任何清理工作都必须由新的客户端进程进行,然后才能充分利用持久连接,从而增加了程序员的负担。

mysqli扩展的持久连接提供了内置的清理处理代码。mysqli进行的清理包括:

Rollback active transactions

Close and drop temporary tables

Unlock tables

Reset session variables

Close prepared statements (always happens with PHP)

Close handler

Release locks acquired with `GET_LOCK()`

这样可以确保在客户端进程使用持久连接之前,从连接池返回的持久连接处于干净状态。

mysqli扩展通过自动调用C-API函数来进行清理mysql_change_user()

自动清除功能虽然有优点也有缺点。好处是程序员不再需要担心添加清除代码,因为它会自动被调用。但是,缺点是该代码可能会稍微慢一些,因为每次从连接池返回连接时都需要运行执行清除的代码。

通过编译带有define的PHP,可以关闭自动清除代码MYSQLI_NO_CHANGE_USER_ON_PCONNECT

注意:

使用MySQL本机驱动程序或MySQL客户端库时,mysqli扩展支持持久连接。

您也可以参考以下链接:http : //www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.