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

ano*_*one 15 mysql

一段时间以来,我一直试图找出一种很好的方法来做到这一点。但是很难找到合适的作品来做到这一点。我猜这一定是可能的。

在这里简单地说就是我想要完成的事情:

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

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

Externally hosted MySQLD
Run Code Online (Sandbox Code Playgroud)

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

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

我恭敬地要求我们不要开始讨论如何不需要持久连接等。它们是。我们的 TIME_WAIT 端口即将用完,并且存在其他问题,如果实施此类系统,这些问题将得到解决。

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

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

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

谢谢!

ano*_*one 12

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

我不是一个作家,所以我会尽我所能把它写得尽可能简洁。

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

SQL中继

http://sqlrelay.sourceforge.net/

这正是问题所要求的,还有更多。我不会详细说明我能够找到的关于此的内容,但会提到它不是一个可行的解决方案,因为它不透明。意思是流程如下:

PHP -> Queries -> SQL Relay Extension -> SQL Relay -> Externally hosted MySQL
Run Code Online (Sandbox Code Playgroud)

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

话虽如此,如果有人正在计划一个需要 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
Run Code Online (Sandbox Code Playgroud)

切换到 mysql-proxy 并让事情解决后:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
     32     192    2848
Run Code Online (Sandbox Code Playgroud)

如您所见,mysql 的 TIME_WAIT 端口几乎没有。

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

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

本地 min_idle_connections

本地 max_idle_connections

这些似乎是不言自明的。除此之外:看起来每个用户名(和密码?未经测试......很可能不是。)组合创建了自己的一组持久连接。

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

所以,让我重申一下,这个小广告为那些通过谷歌搜索的人提供了一些关键词:

使用 PHP 时是否可以在没有 mysql_pconnect 的情况下建立持久的 mysql 连接?

是的,如果您不介意重建大部分代码以通过其扩展或透明地使用 mysql-proxy 和 ro-pooling.lua 脚本来管理您的查询,那么这可以通过 SQL Relay 完成。

我们一直想要这样的东西大约一年了。

请享用!


Mah*_*til 5

  1. PHP 5.3 中为mysqli扩展引入了持久连接支持。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()`
Run Code Online (Sandbox Code Playgroud)

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

mysqli 扩展通过自动调用 C-API 函数来完成这个清理工作mysql_change_user()

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

可以通过使用MYSQLI_NO_CHANGE_USER_ON_PCONNECT定义的方式编译 PHP 来关闭自动清理代码。

笔记:

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

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