Alta disponibilità / scalabilità PostgreSQL con HAProxy e PGBouncer


17

Ho più server PostgreSQL per un'applicazione web. In genere un master e più slave in modalità hot standby (replica streaming asincrona).

Uso PGBouncer per il pool di connessioni: un'istanza installata su ciascun server PG (porta 6432) che si collega al database su localhost. Uso la modalità pool di transazioni.

Per bilanciare il carico delle mie connessioni di sola lettura sugli slave, utilizzo HAProxy (v1.5) con una configurazione più o meno simile a questa:

listen pgsql_pool 0.0.0.0:10001
        mode tcp
        option pgsql-check user ha
        balance roundrobin
        server master 10.0.0.1:6432 check backup
        server slave1 10.0.0.2:6432 check
        server slave2 10.0.0.3:6432 check
        server slave3 10.0.0.4:6432 check

Quindi, la mia applicazione web si connette a haproxy (porta 10001), connessioni di bilanciamento del carico su più pgbouncer configurate su ogni slave PG.

Ecco un grafico di rappresentazione della mia architettura attuale:

haproxy> pgbouncer> postgresql

Funziona abbastanza bene in questo modo, ma mi rendo conto che alcuni lo implementano in modo abbastanza diverso: l'applicazione Web si collega a una singola istanza PGBouncer che si collega a HAproxy che esegue il bilanciamento del carico su più server PG:

pgbouncer> haproxy> postgresql

Qual è l'approccio migliore? Il primo (il mio attuale) o il secondo? Ci sono vantaggi di una soluzione rispetto all'altra?

Grazie

Risposte:


10

La tua configurazione esistente di HAProxy -> PGBouncer -> approch PGServer è migliore. E funziona solo. Ecco il motivo: HAProxy reindirizza la connessione a server diversi. ciò comporta la modifica dell'indirizzo MAC nella connessione al database. Quindi, se PGBouncer è sopra HAProxy, ogni volta che le connessioni nel pool vengono invalidate a causa della modifica dell'indirizzo MAC.


7

pgbouncer mantiene le connessioni in un pool con un server Postgres. I tempi di creazione della connessione TCP sono significativi in ​​un ambiente ad alto volume.

I client che effettuano un gran numero di richieste DB dovranno impostare una connessione con un PGBouncer remoto per ogni richiesta. Questo è più costoso rispetto all'esecuzione di PgBouncer localmente (quindi l'applicazione si collega a pgbouncer localmente) e pgBouncer mantiene un pool di connessioni con il server PG remoto.

Quindi, IMO, PGBouncer -> HAProxy -> PGServer sembra essere migliore di, HAProxy -> PGBouncer -> PGServer, specialmente quando il PGBouncer è locale nell'applicazione client.


1

Non sono d'accordo con la risposta fornita da donatello.

Vedete, se la vostra applicazione non gestisce le connessioni DB usando un pool locale, creerà una nuova connessione ogni volta che dovrà interrogare il DB; succede esattamente lo stesso quando si usa PgBouncer, quindi si otterrà un ottimo miglioramento usandolo.

Quando PgBouncer gestisce le connessioni PostgreSQL raggruppandole, il tempo in cui l'app trascorre l'apertura di una connessione diminuisce in modo significativo, rispetto a quando la connessione viene aperta direttamente al DB. Questo perché PG è piuttosto lento nel controllare e verificare le credenziali e tutto ogni volta che viene richiesta una connessione.

Quindi l'app di approccio -> HAProxy -> [PgBouncer -> PostgreSQL] è la migliore, perché PgBouncer salva i tempi di connessione a PG. Anche la modalità di pooling è importante da tenere in considerazione. Devi essere consapevole del comportamento della tua app. È principalmente transazionale? Oppure, è più di eseguire un mucchio di piccole frasi SQL con una concorrenza elevata? Tutti questi parametri hanno un effetto sulle prestazioni.

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.