PHP -> Mysql pool di connessioni persistenti SENZA mysql_pconnect - Possibile?


12

Ho cercato di capire un bel modo di farlo da un po 'di tempo. Ma ho avuto difficoltà a trovare i pezzi giusti per farlo. Immagino che questo debba essere possibile.

Per dirla in termini semplici, ecco cosa vorrei realizzare:

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

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

Externally hosted MySQLD

Esiste un tale strumento / modo di fare le cose?

Fondamentalmente vorremmo implementare connessioni mysql persistenti SENZA usare mysql_pconnect.

Chiedo rispettosamente che non iniziamo a discutere su come non siano necessarie connessioni persistenti ecc. Lo sono. Stiamo esaurendo le porte TIME_WAIT e stiamo riscontrando altri problemi che sarebbero risolti se questo tipo di sistema fosse implementato.

Quindi sì, per riassumere ... Vorremmo implementare un pool di connessioni mysql che è socket basato sull'estremità locale e persiste le connessioni che sono fatte a un server mysql ospitato esternamente (LAN).

Non utilizziamo transazioni o qualsiasi altra cosa che potrebbe essere influenzata dal riciclo delle connessioni mysql.

Stiamo eseguendo Linux sul front-end con un cluster percona 5.5 master + master.

Grazie!

Risposte:


12

Dopo molte ricerche, ho finalmente trovato una soluzione.

Non sono uno scrittore, quindi farò del mio meglio per renderlo il più conciso possibile.

Per quanto ho potuto trovare, ci sono 2 possibili soluzioni:

Relè SQL

http://sqlrelay.sourceforge.net/

Questo fa esattamente quello che ha posto la domanda e molto altro ancora. Non entrerò in troppi dettagli su ciò che sono stato in grado di scoprire su questo, ma menzionerò che non era una soluzione praticabile in quanto non è trasparente. Ciò significa che il flusso è il seguente:

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

Quindi questo avrebbe comportato la riscrittura di tutto il nostro codice da mysql a sql relay. Non è un'opzione nel nostro caso.

Detto questo, se qualcuno sta pianificando un nuovo progetto su larga scala che richiede una delle numerose funzionalità di SQL Relay, sembra bello.

Mysql Proxy

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

Questa è la soluzione che abbiamo finito per usare.

La chiave per fare questo fare ciò che vogliamo che sia fare è lo script LUA di pooling per il proxy mysql.

Questa estensione LUA è disponibile all'indirizzo:

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

Senza entrare troppo nei dettagli, ecco alcune statistiche di base ... Tenete a mente, questo è testato a BASSO tempo di utilizzo:

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

Dopo essere passati a mysql-proxy e aver risolto le cose:

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

Come puoi vedere chiaramente, le porte TIME_WAIT su mysql sono scese quasi a nessuno.

Le connessioni ora sono infatti persistenti SENZA l'uso di mysql_pconnect / mysqli_connect (... p: hostname ...).

Vale la pena ricordare che sembrano esserci alcune impostazioni configurabili nella parte superiore dello script lua del pooler.

min_idle_connections locali

e

max_idle_connections locali

Questi sembrano essere abbastanza autoesplicativi. Tranne quello: Sembrerebbe che ogni combinazione di nome utente (e password? Non testata ... molto probabilmente non così) crea il proprio set di connessioni persistenti.

Quindi moltiplica max_idle_connections per il numero di utenti mysql unici che si collegheranno al database. E questo dovrebbe darti un'idea di quante connessioni inattive finirai per avere.

Quindi, lasciatemi ripetere, quindi questo piccolo errore colpisce alcune parole chiave per chi cerca tramite Google:

Quando si utilizza PHP è possibile avere connessioni mysql persistenti SENZA mysql_pconnect?

Sì, questo può essere fatto tramite SQL Relay se non ti dispiace ricostruire la maggior parte del codice per reindirizzare le query attraverso la loro estensione O in modo trasparente utilizzando mysql-proxy con lo script ro-pooling.lua.

Desideriamo qualcosa del genere da circa un anno.

GODERE!


Perché non usare semplicemente la funzionalità di pulizia (come indicato dalla risposta seguente) fornita dalla funzione persistente di mysqli ? Se non hai accesso a mysqli, perché non utilizzare mysql_pconnecte avviare semplicemente ogni connessione con alcune "funzioni di pulizia"?
Pacerier,

4
  1. Il supporto di connessione persistente è stato introdotto in PHP 5.3 per l' mysqliestensione. Il supporto era già presente in DOP MYSQL e ext / mysql. L'idea alla base delle connessioni permanenti è che una connessione tra un processo client e un database può essere riutilizzata da un processo client, anziché essere creata e distrutta più volte. Ciò riduce il sovraccarico della creazione di nuove connessioni ogni volta che è necessario, poiché le connessioni non utilizzate vengono memorizzate nella cache e pronte per essere riutilizzate.

  2. A differenza dell'estensione mysql, mysqlinon fornisce una funzione separata per l'apertura di connessioni permanenti. Per aprire una connessione permanente è necessario anteporre p: al nome host durante la connessione.

  3. Il problema con le connessioni persistenti è che possono essere lasciate in stati imprevedibili dai client. Ad esempio, un blocco tabella potrebbe essere attivato prima che un client termini in modo imprevisto. Un nuovo processo client che riutilizza questa connessione persistente otterrà la connessione "così com'è". Qualsiasi pulizia dovrebbe essere effettuata dal nuovo processo client prima che possa fare buon uso della connessione persistente, aumentando l'onere per il programmatore.

La connessione persistente dell'estensione mysqli fornisce tuttavia un codice di gestione della pulizia integrato. La pulizia eseguita da mysqli include:

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

Ciò garantisce che le connessioni permanenti siano in uno stato pulito al ritorno dal pool di connessioni, prima che vengano utilizzate dal processo client.

L'estensione mysqli esegue questa pulizia chiamando automaticamente la funzione C-API mysql_change_user().

La funzione di pulizia automatica presenta tuttavia vantaggi e svantaggi. Il vantaggio è che il programmatore non deve più preoccuparsi di aggiungere il codice di pulizia, come viene chiamato automaticamente. Tuttavia, lo svantaggio è che il codice potrebbe essere potenzialmente un po 'più lento, poiché il codice per eseguire la pulizia deve essere eseguito ogni volta che viene restituita una connessione dal pool di connessioni.

È possibile disattivare il codice di pulizia automatica, compilando PHP con MYSQLI_NO_CHANGE_USER_ON_PCONNECTdefinito.

Nota:

L'estensione mysqli supporta connessioni persistenti quando si utilizza MySQL Native Driver o MySQL Client Library.

Inoltre puoi fare riferimento a questi link: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.