PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

In che modo pgBouncer aiuta a velocizzare Django

Oltre a risparmiare il sovraccarico di connessione e disconnessione dove ciò viene altrimenti eseguito su ciascuna richiesta, un pool di connessioni può incanalare un numero elevato di connessioni client fino a un numero ridotto di connessioni al database effettive. In PostgreSQL, il numero ottimale di connessioni al database attive è solitamente intorno a ((2 * core_count) + Effective_spindle_count) . Al di sopra di questo numero, sia il throughput che la latenza peggiorano.

A volte le persone dicono "Voglio supportare 2000 utenti, con tempi di risposta rapidi". È praticamente garantito che se si tenta di farlo con 2000 connessioni al database effettive, le prestazioni saranno orribili. Se hai una macchina con quattro processori quad-core e il set di dati attivo è completamente memorizzato nella cache, vedrai prestazioni molto migliori per quei 2000 utenti incanalando le richieste attraverso circa 35 connessioni al database.

Per capire perché questo è vero, questo esperimento mentale dovrebbe aiutare. Si consideri un'ipotetica macchina server di database con una sola risorsa da condividere:un singolo core. Questo core suddividerà il tempo in modo uguale tra tutte le richieste simultanee senza sovraccarico. Diciamo che 100 richieste arrivano tutte contemporaneamente, ognuna delle quali richiede un secondo di tempo di CPU. Il nucleo funziona su tutti loro, tagliando il tempo tra di loro fino a quando non finiscono tutti 100 secondi dopo. Ora considera cosa succede se metti davanti un pool di connessioni che accetterà 100 connessioni client ma effettuerà solo una richiesta alla volta al server del database, mettendo in coda tutte le richieste che arrivano mentre la connessione è occupata. Ora, quando arrivano 100 richieste contemporaneamente, un client riceve una risposta in 1 secondo; un altro riceve una risposta in 2 secondi e l'ultimo client riceve una risposta in 100 secondi. Nessuno ha dovuto aspettare più a lungo per ottenere una risposta, il throughput è lo stesso, ma la latenza media è di 50,5 secondi anziché di 100 secondi.

Un vero server di database ha più risorse che possono essere utilizzate in parallelo, ma lo stesso principio vale, una volta che sono saturati, si danneggiano le cose solo aggiungendo più richieste di database simultanee. In realtà è peggio dell'esempio, perché con più attività si hanno più cambi di attività, maggiore contesa per blocchi e cache, contesa sulla riga della cache L2 e L3 e molti altri problemi che riducono sia il throughput che la latenza. Inoltre, mentre un alto work_mem l'impostazione può aiutare una query in diversi modi, tale impostazione è il limite per nodo del piano per ogni connessione , quindi con un numero elevato di connessioni è necessario lasciare questo valore molto piccolo per evitare di svuotare la cache o addirittura portare allo scambio, il che porta a piani più lenti o cose come le tabelle hash che si riversano su disco.

Alcuni prodotti di database creano efficacemente un pool di connessioni nel server, ma la comunità di PostgreSQL ha preso la posizione che, poiché il miglior pool di connessioni è fatto più vicino al software client, lasceranno agli utenti la gestione di questo. La maggior parte dei pooler avrà un modo per limitare le connessioni al database a un numero fisso, consentendo al contempo più richieste client simultanee di così, mettendole in coda se necessario. Questo è quello che vuoi e dovrebbe essere fatto su un transazionale base, non per dichiarazione o connessione.