PHP -> Pool de connexions persistantes Mysql SANS mysql_pconnect - Possible?

12

J'essaie depuis un certain temps de trouver une belle façon de le faire. Mais j'ai eu du mal à trouver les bonnes pièces pour le faire. Je suppose que cela doit être possible.

Pour le dire simplement, voici ce que j'aimerais accomplir:

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

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

Externally hosted MySQLD

Existe-t-il un tel outil / façon de faire les choses?

Nous aimerions essentiellement implémenter des connexions mysql persistantes SANS utiliser mysql_pconnect.

Je demande respectueusement que nous ne commencions pas à discuter de la façon dont les connexions persistantes ne sont pas nécessaires, etc. Elles le sont. Nous manquons de ports TIME_WAIT et rencontrons d'autres problèmes qui seraient résolus si ce type de système était implémenté.

Alors oui, pour résumer ... Nous voudrions implémenter un pool de connexion mysql qui est socket basé sur l'extrémité locale, et qui persiste les connexions qui sont faites à un serveur mysql hébergé en externe (LAN).

Nous n'utilisons pas de transactions ou toute autre chose qui pourrait être affectée par le recyclage des connexions mysql.

Nous utilisons Linux sur le front-end avec un cluster maître + maître percona 5.5.

Merci!

anonyme-un
la source

Réponses:

12

Après de longues recherches, j'ai finalement trouvé une solution.

Je ne suis pas très écrivain, je ferai donc de mon mieux pour que cela soit aussi concis que possible.

Pour autant que je puisse trouver, il y a 2 solutions possibles:

Relais SQL

http://sqlrelay.sourceforge.net/

Cela fait exactement ce que la question demandait, et bien plus encore. Je n'entrerai pas dans trop de détails sur ce que j'ai pu découvrir à ce sujet, mais je mentionnerai que ce n'était pas une solution viable car elle n'est pas transparente. Cela signifie que le flux est le suivant:

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

Cela aurait donc impliqué de réécrire tout notre code de mysql vers sql relay. Pas une option dans notre cas.

Cela étant dit, si quelqu'un prévoit un nouveau projet à grande échelle qui nécessite l'une des nombreuses fonctionnalités de SQL Relay, cela semble magnifique.

Mysql Proxy

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

C'est la solution que nous avons finalement utilisée.

La clé pour faire faire ce que nous voulons qu'il fasse est le script de pooling LUA pour le proxy mysql.

Cette extension LUA est disponible à l'adresse suivante:

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

Sans entrer dans trop de détails, voici quelques statistiques de base ... A l'esprit, elles sont testées à faible temps d'utilisation:

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

Après être passé à mysql-proxy et avoir laissé les choses se régler:

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

Comme vous pouvez le voir clairement, les ports TIME_WAIT vers mysql sont tombés à presque aucun.

Les connexions sont maintenant en fait persistantes SANS utiliser mysql_pconnect / mysqli_connect (... p: hostname ...).

Il convient de mentionner qu'il semble y avoir quelques paramètres configurables près du haut du script pooler lua.

connexions locales min_idle_connections

et

max_idle_connections locales

Ceux-ci semblent assez explicites. Sauf que: Il semblerait que chaque combinaison de nom d'utilisateur (et de mot de passe? Non testé ... probablement pas le cas) crée son propre ensemble de connexions persistantes.

Multipliez donc max_idle_connections par le nombre d'utilisateurs mysql uniques qui se connecteront à la base de données. Et cela devrait vous donner une idée du nombre de connexions inactives que vous finirez par avoir.

Alors, permettez-moi de répéter pour que ce petit texte de présentation frappe certains mots clés pour ceux qui recherchent via Google:

Lors de l'utilisation de PHP, est-il possible d'avoir des connexions mysql persistantes SANS mysql_pconnect?

Oui, cela peut être fait via SQL Relay si cela ne vous dérange pas de reconstruire la plupart de votre code pour diriger vos requêtes via leur extension OU de manière transparente en utilisant mysql-proxy avec le script ro-pooling.lua.

Nous voulons quelque chose comme ça depuis environ un an maintenant.

PRENDRE PLAISIR!

anonyme-un
la source
Pourquoi ne pas simplement utiliser la fonctionnalité de nettoyage (comme indiqué par la réponse ci-dessous) fournie par la fonction persistante de mysqli ? Si vous n'avez pas accès à mysqli, pourquoi ne pas simplement utiliser mysql_pconnectet démarrer chaque connexion avec quelques "fonctions de nettoyage"?
Pacerier
4
  1. Le support de connexion persistante a été introduit en PHP 5.3 pour l' mysqliextension. Le support était déjà présent dans PDO MYSQL et ext / mysql. L'idée derrière les connexions persistantes est qu'une connexion entre un processus client et une base de données peut être réutilisée par un processus client, plutôt que d'être créée et détruite plusieurs fois. Cela réduit la surcharge de création de nouvelles connexions chaque fois qu'une connexion est nécessaire, car les connexions inutilisées sont mises en cache et prêtes à être réutilisées.

  2. Contrairement à l'extension mysql, mysqline fournit pas de fonction distincte pour ouvrir des connexions persistantes. Pour ouvrir une connexion persistante, vous devez ajouter p: au nom d'hôte lors de la connexion.

  3. Le problème avec les connexions persistantes est qu'elles peuvent être laissées dans des états imprévisibles par les clients. Par exemple, un verrou de table peut être activé avant qu'un client ne se termine de façon inattendue. Un nouveau processus client réutilisant cette connexion persistante obtiendra la connexion "telle quelle". Tout nettoyage devrait être effectué par le nouveau processus client avant de pouvoir faire bon usage de la connexion persistante, augmentant ainsi la charge du programmeur.

La connexion persistante de l'extension mysqli fournit cependant un code de gestion de nettoyage intégré. Le nettoyage effectué par mysqli comprend:

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

Cela garantit que les connexions persistantes sont dans un état propre au retour du pool de connexions, avant que le processus client ne les utilise.

L'extension mysqli effectue ce nettoyage en appelant automatiquement la fonction C-API mysql_change_user().

La fonction de nettoyage automatique présente cependant des avantages et des inconvénients. L'avantage est que le programmeur n'a plus à se soucier de l'ajout de code de nettoyage, car il est appelé automatiquement. Cependant, l'inconvénient est que le code pourrait être un peu plus lent, car le code pour effectuer le nettoyage doit s'exécuter chaque fois qu'une connexion est renvoyée du pool de connexions.

Il est possible de désactiver le code de nettoyage automatique, en compilant PHP avec MYSQLI_NO_CHANGE_USER_ON_PCONNECTdéfini.

Remarque:

L'extension mysqli prend en charge les connexions persistantes lors de l'utilisation de MySQL Native Driver ou MySQL Client Library.

Vous pouvez également consulter ces liens: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

Mahesh Patil
la source