PHP -> Agrupación de conexiones persistentes Mysql SIN mysql_pconnect - ¿Posible?

12

He estado tratando de encontrar una buena manera de hacer esto por un tiempo. Pero he tenido dificultades para encontrar las piezas adecuadas para hacer esto. Supongo que esto debe ser posible.

Para ponerlo en términos simples, esto es lo que me gustaría lograr:

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

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

Externally hosted MySQLD

¿Existe tal herramienta / forma de hacer las cosas?

Básicamente nos gustaría implementar conexiones persistentes de mysql SIN usar mysql_pconnect.

Respetuosamente pido que no comencemos a discutir sobre cómo no se necesitan conexiones persistentes, etc. Nos estamos quedando sin puertos TIME_WAIT y tenemos otros problemas que se resolverían si se implementara este tipo de sistema.

Entonces, para resumir ... Implementaríamos un agrupador de conexiones mysql que es socket basado en el extremo local, y persiste las conexiones que se hacen a un servidor mysql alojado externamente (LAN).

No utilizamos transacciones ni nada que se vea afectado por las conexiones mysql que se reciclan.

Estamos ejecutando Linux en el front-end con un clúster master + master percona 5.5.

¡Gracias!

anónimo uno
fuente

Respuestas:

12

Después de mucho buscar, finalmente he encontrado una solución.

No soy muy escritor, así que haré todo lo posible para que esto sea lo más conciso posible.

Por lo que pude encontrar, hay 2 posibles soluciones:

Retransmisión SQL

http://sqlrelay.sourceforge.net/

Esto hace exactamente lo que pidió la pregunta, y un montón más. No entraré en demasiados detalles sobre lo que pude averiguar sobre esto, pero mencionaré que no era una solución viable ya que no es transparente. Lo que significa que el flujo es el siguiente:

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

Entonces, esto habría implicado reescribir todo nuestro código de mysql a sql relay. No es una opción en nuestro caso.

Dicho todo esto, si alguien está planeando un nuevo proyecto a gran escala que requiera cualquiera de las numerosas características que tiene SQL Relay, suena hermoso.

Proxy Mysql

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

Esta es la solución que terminamos usando.

La clave para hacer que esto haga lo que queremos que haga es el script LUA de agrupación para el proxy mysql.

Esta extensión LUA se puede encontrar en:

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

Sin entrar en demasiados detalles, aquí hay algunas estadísticas básicas ... Ten en cuenta que esto se prueba con un tiempo de uso BAJO:

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

Después de cambiar a mysql-proxy y dejar que las cosas se resuelvan:

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

Como puede ver claramente, los puertos TIME_WAIT a mysql se han reducido a casi ninguno.

Las conexiones ahora son de hecho persistentes SIN usar mysql_pconnect / mysqli_connect (... p: hostname ...).

Vale la pena mencionar que parece haber algunas configuraciones configurables cerca de la parte superior del script lua de pooler.

min_idle_connections locales

y

max_idle_connections locales

Estos parecen ser bastante explicativos. Excepto que: Parece que cada combinación de nombre de usuario (y contraseña no probada ... probablemente no) crea su propio conjunto de conexiones persistentes.

Entonces multiplique max_idle_connections por la cantidad de usuarios únicos de mysql que se conectarán a la base de datos. Y eso debería darte una idea de cuántas conexiones inactivas terminarás teniendo.

Entonces, permítanme reiterarlo para que esta pequeña propaganda llegue a algunas palabras clave para aquellos que buscan a través de Google:

Cuando se usa PHP, ¿es posible tener conexiones persistentes de mysql SIN mysql_pconnect?

Sí, esto se puede hacer a través de SQL Relay si no le importa reconstruir la mayoría de su código para canalizar sus consultas a través de su extensión O de forma transparente usando mysql-proxy con el script ro-pooling.lua.

Hemos estado esperando algo como esto durante aproximadamente un año.

¡DISFRUTAR!

anónimo uno
fuente
¿Por qué no simplemente usar la funcionalidad de limpieza (como se indica en la respuesta a continuación) proporcionada por la función persistente de mysqli ? Si no tiene acceso a mysqli, ¿por qué no simplemente usar mysql_pconnecte iniciar cada conexión con algunas "funciones de limpieza"?
Pacerier
4
  1. El soporte de conexión persistente se introdujo en PHP 5.3 para la mysqliextensión. El soporte ya estaba presente en PDO MYSQL y ext / mysql. La idea detrás de las conexiones persistentes es que una conexión entre un proceso de cliente y una base de datos puede ser reutilizada por un proceso de cliente, en lugar de ser creada y destruida varias veces. Esto reduce la sobrecarga de crear conexiones nuevas cada vez que se requiere una, ya que las conexiones no utilizadas se almacenan en caché y están listas para ser reutilizadas.

  2. A diferencia de la extensión mysql, mysqlino proporciona una función separada para abrir conexiones persistentes. Para abrir una conexión persistente, debe anteponer p: al nombre de host al conectarse.

  3. El problema con las conexiones persistentes es que los clientes pueden dejarlas en estados impredecibles. Por ejemplo, un bloqueo de tabla puede activarse antes de que un cliente finalice inesperadamente. Un nuevo proceso de cliente que reutilice esta conexión persistente obtendrá la conexión "tal cual". El proceso del nuevo cliente deberá realizar cualquier limpieza antes de que pueda hacer un buen uso de la conexión persistente, aumentando la carga sobre el programador.

Sin embargo, la conexión persistente de la extensión mysqli proporciona un código de manejo de limpieza incorporado. La limpieza realizada por mysqli incluye:

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()`

Esto garantiza que las conexiones persistentes estén en estado limpio al regresar del grupo de conexiones, antes de que el proceso del cliente las use.

La extensión mysqli realiza esta limpieza llamando automáticamente a la función C-API mysql_change_user().

Sin embargo, la función de limpieza automática tiene ventajas y desventajas. La ventaja es que el programador ya no necesita preocuparse por agregar el código de limpieza, ya que se llama automáticamente. Sin embargo, la desventaja es que el código podría ser un poco más lento, ya que el código para realizar la limpieza debe ejecutarse cada vez que se devuelve una conexión del grupo de conexiones.

Es posible desactivar el código de limpieza automática, compilando PHP con MYSQLI_NO_CHANGE_USER_ON_PCONNECTdefinido.

Nota:

La extensión mysqli admite conexiones persistentes cuando se usa MySQL Native Driver o MySQL Client Library.

También puede consultar estos enlaces: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent- connections- evil/

Mahesh Patil
fuente