A seguito di Tuning Linux for Low PostgreSQL Latency del mese scorso, ora c'è stato un enorme mucchio di test eseguiti su due filesystem, tre patch e due set di parametri di ottimizzazione del kernel eseguiti. Il risultato finora sono alcuni nuovi dati interessanti e un altro miglioramento impegnato in quest'area che ora è in PostgreSQL 9.1 (per un totale di tre, gli altri due stanno monitorando le patch). Parlerò della pratica consigliata il mese prossimo durante uno dei miei discorsi a PostgreSQL East e ho presentato qualcosa in quest'area anche per il PGCon di maggio. Qui parlerò ancora un po' dei vicoli ciechi, mentre quei ricordi sono ancora freschi.
Il problema di base qui è che il modo in cui PostgreSQL utilizza la cache del sistema operativo durante la scrittura consente l'accumulo di grandi quantità di dati. Il risultato al termine dei checkpoint del database può causare lunghi ritardi durante l'attesa della scrittura dei dati. Si scopre che il programma pgbench fornito con PostgreSQL è davvero bravo a creare questo problema, quindi è quello che ho usato per tutti i test. Le domande sui mezzi a cui mi sono proposto di rispondere erano:
- Il cambiamento dal vecchio filesystem ext3 mostra davvero un miglioramento delle prestazioni sulle attività del database? Ho scritto qualcosa sul ritorno di XFS su Linux l'anno scorso che ha mostrato un bel miglioramento rispetto ai benchmark semplici. Tuttavia, ciò non si traduce sempre in miglioramenti del database.
- I recenti sintonizzabili di Linux dirty_bytes e dirty_background_bytes migliorano davvero la latenza nel caso peggiore?
- Quali delle modifiche al database suggerite per migliorare il comportamento qui funzionano davvero?
Puoi vedere tutti i risultati del test se vuoi controllare i dati grezzi. Ciò che è stato modificato per ogni set di test è documentato e, se si approfondisce un singolo test, è possibile visualizzare i parametri del database utilizzati e alcune altre informazioni di base sul sistema operativo. Quella pagina web è ciò che esce dal mio programma di test pgbench-tools, se vuoi provare tu stesso questo genere di cose.
I risultati non sono stati molto sorprendenti, ma sono stati interessanti. Tutti i test qui sono stati eseguiti con due dimensioni del database. Con una dimensione del database più piccola (scala =500, circa un database da 8 GB che si adatta facilmente ai 16 GB di RAM del server), ext3 ha gestito 690 transazioni al secondo, mentre con una dimensione doppia (scala =1000, circa un database da 16 GB) era molto più ricerca vincolata e gestita solo 349 TPS. XFS ha aumentato questi due numeri a 1757 TPS e 417 TPS, rispettivamente del 255% e del 19%. Ancora meglio, la latenza nel caso peggiore per una singola transazione è scesa dall'intervallo da 34 a 56 secondi (!) a quello da 2 a 5 secondi. Sebbene anche 5 secondi non siano eccezionali, questo è un carico di lavoro sintetico progettato per rendere questo problema davvero grave. I numeri ext3 sono così terribili che è ancora molto probabile che si verifichi un brutto problema qui, anche se in realtà stavo vedendo un comportamento migliore su quel filesystem di quello che ho visto nei kernel precedenti (questo è stato fatto con 2.6.32).
Round 1: XFS vince in maniera schiacciante. Non posso raccomandare ext3 come un filesystem valido su sistemi Linux con molta memoria se prevedi di scrivere pesantemente; semplicemente non funziona in quel contesto. Questo server aveva solo 16 GB di RAM, quindi puoi immaginare quanto sia grave questo problema su un server di produzione serio qui nel 2011.
Successivamente, i parametri sintonizzabili dirty_bytes e dirty_background_bytes. Questi due hanno migliorato un po' la latenza su ext3, a scapito di alcuni rallentamenti. Il peggiore di questi, tempo di manutenzione rallentato con VACUUM, non si vede nei risultati dei test stessi; Ne ho già parlato nel mio precedente post sul blog. Su XFS, la riduzione di questi parametri è un disastro per le prestazioni. Su una scala di database più piccola, le prestazioni del TPS diminuiscono del 46% e, per di più, la latenza peggiora.
Round 2: Non aspettarti miracoli da dirty_bytes o dirty_background_bytes. Sembrano avere qualche effetto positivo in alcune circostanze, ma anche il potenziale svantaggio è grande. Assicurati di testare attentamente e includi VACUUM nei tuoi test prima di regolare questi due verso il basso.
Successivamente, ho finito per valutare tre idee di patch per PostgreSQL come parte di quest'ultimo CommitFest:
- Distribuisci la sincronizzazione del checkpoint su disco (fsync) nel tempo. Avevamo riscontrato un certo successo su un server client occupato se combinato con una migliore gestione del modo in cui altre operazioni di sincronizzazione venivano memorizzate nella cache dal database
- Richieste fsync compatte. Questa idea è nata dalla prima e si è trasformata in una patch scritta da Robert Haas. L'idea è che i client che tentano di sincronizzare i dati su disco potrebbero essere in competizione con la scrittura del checkpoint. Ciò che fa la patch è consentire ai client di ripulire la coda delle richieste fsync se la trovano piena.
- Ordina le scritture del checkpoint. Il concetto è che se scrivi le cose nell'ordine in cui il database ritiene che le cose siano archiviate su disco, il sistema operativo potrebbe scrivere in modo più efficiente. Questa patch si è presentata alcuni anni fa con alcuni risultati di benchmark che suggerivano che funzionasse, ma all'epoca nessuno era in grado di replicare i miglioramenti. L'idea si adattava abbastanza bene al resto del lavoro che l'ho valutata di nuovo.
Round 3: Dopo settimane di tentativi, l'unico approccio di questo set che ha mostrato il miglioramento in quasi tutte le dimensioni del carico di lavoro è stato quello di compattazione fsync. Il codice di sincronizzazione del checkpoint di diffusione originale ha aiutato alcuni in quest'area, ma l'implementazione specifica ora impegnata per 9.1 ha funzionato ancora meglio. È stato un guadagno quasi totale del 10% sulla maggior parte dei test di scrittura pesanti che ho eseguito. Questo è un grande miglioramento per PostgreSQL 9.1 e dovrebbe eliminare completamente un problema che abbiamo visto causare un rallentamento molto maggiore sui sistemi di produzione qui.
Il resto delle idee qui non ha ricevuto una valutazione così positiva dopo pesanti benchmarking, quindi per ora quelli tornano sullo scaffale. Continuerò a raccogliere dati qui – alcuni test ext4 sono la prossima cosa logica da provare – e poi tornerò di nuovo allo sviluppo. Ottenere un guadagno del 10% su alcuni carichi di lavoro difficili è sicuramente positivo, ma ci sono ancora troppi comportamenti peggiori qui per considerare i problemi di sincronizzazione dei checkpoint un argomento chiuso.