PHP -> Mysql persistentes Connection Pooling OHNE mysql_pconnect - Möglich?

12

Ich habe schon seit einiger Zeit versucht, eine gute Möglichkeit zu finden, dies zu tun. Aber es fiel mir schwer, die richtigen Stücke dafür zu finden. Ich vermute, das muss möglich sein.

Einfach ausgedrückt ist das, was ich erreichen möchte:

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

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

Externally hosted MySQLD

Gibt es ein solches Werkzeug / eine solche Methode?

Wir möchten grundsätzlich persistente MySQL-Verbindungen ohne Verwendung von MySQL_Pconnect implementieren.

Ich bitte respektvoll darum, dass wir nicht anfangen, darüber zu diskutieren, wie dauerhaft Verbindungen nicht benötigt werden usw. Sie sind. Wir haben keine TIME_WAIT-Ports mehr und andere Probleme, die gelöst werden könnten, wenn dieser Systemtyp implementiert würde.

Also ja, um es zusammenzufassen ... Wir würden einen MySQL-Verbindungspooler implementieren, der auf dem lokalen Ende basiert und die Verbindungen, die zu einem (LAN) extern gehosteten MySQL-Server hergestellt werden, beibehält.

Wir verwenden keine Transaktionen oder andere Dinge, die von den wiederherzustellenden MySQL-Verbindungen betroffen sind.

Wir betreiben Linux auf dem Frontend mit einem Master + Master Percona 5.5 Cluster.

Vielen Dank!

anonym eins
quelle

Antworten:

12

Nach langem Suchen habe ich endlich eine Lösung gefunden.

Ich bin kein großer Schriftsteller, deshalb werde ich mein Bestes geben, um dies so kurz wie möglich zu halten.

Soweit ich das beurteilen konnte, gibt es zwei mögliche Lösungen:

SQL-Relay

http://sqlrelay.sourceforge.net/

Dies macht genau das, was die Frage verlangt, und ein paar mehr. Ich werde nicht zu sehr ins Detail gehen, was ich darüber herausfinden konnte, aber ich werde erwähnen, dass es keine praktikable Lösung war, da es nicht transparent ist. Dies bedeutet, dass der Fluss wie folgt ist:

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

Das hätte also dazu geführt, dass wir unseren gesamten Code von MySQL auf SQL Relay umgeschrieben hätten. In unserem Fall keine Option.

Wenn jedoch jemand ein neues Großprojekt plant, das eine der zahlreichen Funktionen von SQL Relay erfordert, klingt dies sehr schön.

Mysql Proxy

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

Dies ist die Lösung, die wir letztendlich verwendet haben.

Der Schlüssel dazu ist das Pooling-LUA-Skript für den MySQL-Proxy.

Diese LUA-Erweiterung finden Sie unter:

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

Hier sind einige grundlegende Statistiken, ohne auf allzu viele Details einzugehen.

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

Nachdem Sie zu mysql-proxy gewechselt und die Dinge regeln lassen haben:

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

Wie Sie deutlich sehen können, sind die TIME_WAIT-Ports für mysql auf fast keinen gesunken.

Die Verbindungen bleiben nun tatsächlich OHNE mysql_pconnect / mysqli_connect (... p: hostname ...) bestehen.

Erwähnenswert sind anscheinend einige konfigurierbare Einstellungen oben im pooler lua-Skript.

lokale min_idle_connections

und

lokale max_idle_connections

Diese scheinen ziemlich selbsterklärend zu sein. Ausgenommen das: Es scheint, dass jede Kombination aus Benutzername (und Passwort? Ungetestet ... höchstwahrscheinlich nicht.) Einen eigenen Satz persistenter Verbindungen erzeugt.

Multiplizieren Sie also max_idle_connections mit der Anzahl der eindeutigen MySQL-Benutzer, die eine Verbindung zur Datenbank herstellen. Und das sollte Ihnen eine Vorstellung davon geben, wie viele freie Verbindungen Sie am Ende haben werden.

Lassen Sie mich noch einmal wiederholen, damit dieser kleine Klappentext einige Keywords für Suchende über Google enthält:

Ist es bei Verwendung von PHP möglich, dauerhafte MySQL-Verbindungen OHNE MySQL_Pconnect zu haben?

Ja, dies kann über SQL Relay erfolgen, wenn es Ihnen nichts ausmacht, den größten Teil Ihres Codes neu zu erstellen, um Ihre Abfragen durch ihre Erweiterung zu leiten, ODER wenn Sie mysql-proxy mit dem Skript ro-pooling.lua transparent verwenden.

So etwas wollen wir schon seit einem Jahr.

GENIESSEN!

anonym eins
quelle
Warum nicht einfach die Bereinigungsfunktion (wie in der Antwort unten angegeben) verwenden, die von der persistenten Funktion von mysqli bereitgestellt wird ? Wenn Sie keinen Zugriff auf mysqli haben, warum nicht einfach mysql_pconnectjede Verbindung mit einigen "Bereinigungsfunktionen" verwenden und starten?
Pacerier
4
  1. Persistent Connection Support wurde in PHP 5.3 für die mysqliErweiterung eingeführt. Unterstützung gab es bereits in PDO MYSQL und ext / mysql. Die Idee hinter dauerhaften Verbindungen ist, dass eine Verbindung zwischen einem Client-Prozess und einer Datenbank von einem Client-Prozess wiederverwendet werden kann, anstatt mehrmals erstellt und zerstört zu werden. Dies reduziert den Aufwand für das Erstellen neuer Verbindungen bei jeder Anforderung, da nicht verwendete Verbindungen zwischengespeichert werden und zur Wiederverwendung bereit sind.

  2. Bietet im Gegensatz zur mysql-Erweiterung mysqlikeine separate Funktion zum Öffnen dauerhafter Verbindungen. Um eine dauerhafte Verbindung herzustellen, müssen Sie beim Herstellen der Verbindung dem Hostnamen p: voranstellen.

  3. Das Problem bei dauerhaften Verbindungen besteht darin, dass sie von Clients in unvorhersehbaren Zuständen belassen werden können. Beispielsweise kann eine Tabellensperre aktiviert werden, bevor ein Client unerwartet beendet wird. Ein neuer Client-Prozess, der diese persistente Verbindung wiederverwendet, erhält die Verbindung "wie sie ist". Jede Bereinigung muss vom neuen Client-Prozess durchgeführt werden, bevor er die dauerhafte Verbindung nutzen und den Programmierer entlasten kann.

Die dauerhafte Verbindung der mysqli-Erweiterung bietet jedoch integrierten Code für die Bereinigungsbehandlung. Die von mysqli durchgeführte Bereinigung beinhaltet:

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

Dadurch wird sichergestellt, dass persistente Verbindungen bei der Rückkehr aus dem Verbindungspool in einem sauberen Zustand sind, bevor der Clientprozess sie verwendet.

Die mysqli-Erweiterung führt diese Bereinigung durch, indem sie automatisch die C-API-Funktion aufruft mysql_change_user().

Die automatische Bereinigung bietet jedoch Vor- und Nachteile. Der Vorteil ist, dass sich der Programmierer nicht mehr um das Hinzufügen von Bereinigungscode kümmern muss, da dieser automatisch aufgerufen wird. Der Nachteil ist jedoch, dass der Code möglicherweise etwas langsamer ist, da der Code zum Ausführen der Bereinigung jedes Mal ausgeführt werden muss, wenn eine Verbindung aus dem Verbindungspool zurückgegeben wird.

Es ist möglich, den automatischen Bereinigungscode auszuschalten, indem PHP mit MYSQLI_NO_CHANGE_USER_ON_PCONNECTdefined kompiliert wird .

Hinweis:

Die mysqli-Erweiterung unterstützt dauerhafte Verbindungen, wenn Sie entweder MySQL Native Driver oder MySQL Client Library verwenden.

Sie können auch auf diese Links verweisen: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

Mahesh Patil
quelle