Configurazione di PostgreSQL per le prestazioni di scrittura


30

Uno dei miei server PostgreSQL ospita diversi (1-3) database che ricevono un flusso costante di dati. I dati non sono particolarmente strutturati, ammontano al tempo corrente e ad una varietà di dati osservati per quel particolare istante. La velocità dei dati è piuttosto elevata; funziona a circa un gigabyte al giorno per un database, circa un decimo di quello per un altro database. Non mi aspetto che questo tasso aumenti. Le prestazioni di lettura hanno una priorità molto più bassa ed è attualmente accettabile.

Nei registri ho questo messaggio:

LOG:  checkpoints are occurring too frequently (15 seconds apart)
HINT:  Consider increasing the configuration parameter "checkpoint_segments".

Questo valore è attualmente impostato su 16, per gentile concessione di pgtune.

Quali sono le impostazioni che dovrei considerare per migliorare le prestazioni di scrittura? Preferirei mantenere la massima sicurezza possibile. Considerando il volume di dati in arrivo, potrei accettare di perdere alcuni dati recenti in caso di errore purché la maggior parte dei dati fosse intatta.

Modifica: sto usando PostgreSQL 9.0 per ora, ma ho intenzione di aggiornare a 9.1. Non sto pubblicando i dettagli dell'hardware perché, mentre riconosco la loro importanza, alla fine dovrò fare questa ottimizzazione su più macchine con hardware molto diverso. Se l'hardware è essenziale per la risposta, ti prego di darmi le informazioni generali in modo da poter applicare la risposta a macchine con diverse configurazioni hardware.


Puoi pubblicare la tua versione e preferibilmente alcuni dettagli sull'hardware di archiviazione?
Jack Douglas,

Hai aumentato checkpoint_segmentscome raccomandato? Quello che è successo?
a_horse_with_no_name

3
Un'altra eccellente risorsa per questo tipo di domande è il libro di Gregory Smith PostgreSQL 9.0 High Performance .
jp

Risposte:


24

1 Gigabyte al giorno non è così elevato di un carico di scrittura. Distribuito per tutto il giorno, arriva a circa 50 kbyte al secondo. Una chiavetta USB lenta potrebbe gestirlo. Presumo che sia più scoppiato però. Come suggerisce a_horse_with_no_name, aumenta i segmenti del checkpoint. 100 o giù di lì non è fuori dal comune.

Quindi aumenta la tua checkpoint_timeouta 1 ora e cerca di aumentare la tua checkpoint_completion_targeta qualcosa di più vicino a 1,0 (100%). Il target di completamento dice a PostgreSQL quanto aggressivamente scrivere in background in modo che sia x% completo prima di eseguire un checkpoint, che forza tutti i dati da scrivere immediatamente dal WAL e rallenta il sistema a una scansione mentre sta accadendo.

Il motivo per cui di solito non lo si imposta al 100% è che è abbastanza comune scrivere nello stesso blocco più di una volta e, ritardando le scritture WAL nello store principale, si impedisce che lo stesso blocco venga scritto due volte senza motivo.

Se è improbabile che tu scriva sullo stesso blocco più di una volta prima che si verifichi il timeout, ovvero tutto ciò che fai è inserire quindi impostarlo su un valore abbastanza alto ha senso alzarlo a 0,9 o giù di lì. Il peggio che accadrà è che scriverai un po 'più spesso di quanto potresti altrimenti fare, ma l'impatto dei punti di controllo sarà notevolmente ridotto.


Il volume di scrittura è in realtà quasi completamente uniforme: questo è l'archivio dati per il software di monitoraggio hardware che esegue il polling ogni secondo, continuamente, 24x7. Potrei calcolare l'esatta velocità dei dati, ma fluttua leggermente quando i programmatori aggiungono e rimuovono i punti di monitoraggio.
Daniel Lyons,

1
Bene, se il tasso è 1G al giorno ed è regolare, allora quasi tutti i sottosistemi possono gestire il carico di scrittura, vuoi solo mantenerlo regolare, il cui obiettivo di completamento del checkpoint è impostato vicino a 1,0 e un timeout di checkpoint lungo dovrebbe farti.
Scott Marlowe,

10

In un sistema molto 'write heavy', è probabile che tu sia limitato dalla velocità che WAL può scrivere durante l'attività di picco.

Se riesci davvero a "accettare la perdita di alcuni dati recenti in caso di errore", puoi disattivare il commit sincrono che:

può essere un'alternativa utile quando le prestazioni sono più importanti della certezza esatta sulla durata di una transazione

Se sei in grado di cambiare l'hardware, potresti considerare uno di questi per ottimizzare le scritture:

  • RAID10 su RAID5
  • Molti mandrini (ad esempio potrebbe significare 2,5 "anziché 3,5")
  • SAS su SATA
  • 15K su 10K unità
  • SSD

--modificare

Sulla base del tuo commento sull'eccellente risposta di @ Scott : "Il volume di scrittura è in realtà quasi completamente uniforme" e la velocità di dati implicita di "50kbyte al secondo", dubito che tu debba fare tutto ciò che rischia di perdere i dati. Forse sarebbe utile sapere su quali altri parametri di configurazione sono impostati.


3
Se le prestazioni di scrittura sono importanti, un controller alimentato a batteria tra il sistema operativo e i dischi rigidi in rotazione può fare una differenza ENORME.
Scott Marlowe,

5

Potresti anche verificare la frequenza / dimensione dei tuoi commit: di recente ho riscontrato un problema in cui stavo cercando di aggiornare> 1 milione di record in una singola transazione. Ho ricevuto messaggi di registro simili a quelli descritti da OP, ma la transazione non è stata completata anche dopo diverse ore. Quando ho suddiviso la scrittura in diverse transazioni più piccole (10.000 record circa), il tempo totale richiesto è sceso a circa 15 minuti.

Quello che penso sia successo è che Postgres ha trascorso così tanto tempo a scrivere i registri che checkpoint_timeout è trascorso prima che potesse fare progressi sostanziali salvando i record. Non sono sicuro se questa spiegazione regge. Ricevo ancora gli avvisi, ma alla fine tutte le scritture vengono elaborate. Tuttavia, avevo bisogno (e ho trovato) una soluzione programmatica piuttosto che una che richiedesse la riconfigurazione del database.

Vedi anche http://www.postgresql.org/docs/9.3/static/wal-configuration.html

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.