it-swarm-eu.dev

Konfigurieren von PostgreSQL für die Schreibleistung

Einer meiner PostgreSQL-Server hostet mehrere (1-3) Datenbanken, die einen konstanten Datenstrom empfangen. Die Daten sind nicht besonders strukturiert, sie entsprechen der aktuellen Zeit und einer Vielzahl von beobachteten Daten für diesen bestimmten Zeitpunkt. Die Datenrate ist ziemlich hoch; Für eine Datenbank beträgt das ungefähr ein Gigabyte pro Tag, für eine andere ungefähr ein Zehntel. Ich erwarte keinen Anstieg dieser Rate. Die Leseleistung hat eine viel niedrigere Priorität und ist derzeit akzeptabel.

In den Protokollen habe ich diese Nachricht:

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

Dieser Wert ist derzeit auf 16 festgelegt, was mit freundlicher Genehmigung von pgtune erfolgt.

Welche Einstellungen sollte ich berücksichtigen, um die Schreibleistung zu verbessern? Ich würde es vorziehen, so viel Sicherheit wie möglich zu behalten. In Anbetracht des eingehenden Datenvolumens könnte ich akzeptieren, dass bei einem Fehler einige aktuelle Daten verloren gehen, solange der Großteil der Daten intakt ist.

Bearbeiten: Ich verwende derzeit PostgreSQL 9.0, plane jedoch ein Upgrade auf 9.1. Ich veröffentliche die Hardwaredetails nicht, da ich zwar ihre Bedeutung anerkenne, diese Optimierung jedoch letztendlich auf mehreren Computern mit sehr unterschiedlicher Hardware durchführen muss. Wenn die Hardware für die Antwort wesentlich ist, geben Sie mir bitte die allgemeinen Informationen, damit ich die Antwort auf Maschinen mit unterschiedlichen Hardwarekonfigurationen anwenden kann.

30
Daniel Lyons

1 Gigabyte pro Tag ist keine so hohe Schreiblast. Verteilt über den Tag, ergibt dies ungefähr 50 KByte pro Sekunde. Ein langsamer USB-Stick könnte damit umgehen. Ich gehe davon aus, dass es mehr platzt. Erhöhen Sie, wie a_horse_with_no_name vorschlägt, die Checkpoint-Segmente. 100 oder so ist nicht ungewöhnlich.

Dann erhöhen Sie Ihre checkpoint_timeout auf 1 Stunde, sowie schauen Sie sich die Erhöhung Ihrer checkpoint_completion_target auf etwas näher an 1,0 (100%). Das Abschlussziel teilt PostgreSQL mit, wie aggressiv im Hintergrund geschrieben werden soll, damit es x% vollständig ist, bevor ein Prüfpunkt ausgeführt wird. Dadurch werden alle Daten auf einmal aus der WAL geschrieben und das System wird während des Vorgangs zu einem Crawlen verlangsamt.

Der Grund, warum Sie es normalerweise nicht auf 100% setzen, ist, dass es ziemlich häufig ist, mehr als einmal in denselben Block zu schreiben. Wenn Sie das Schreiben von WAL in den Hauptspeicher verzögern, verhindern Sie, dass derselbe Block ohne Grund zweimal geschrieben wird.

Wenn es unwahrscheinlich ist, dass Sie mehr als einmal vor dem Timeout in denselben Block schreiben, d. H. Alles, was Sie tun, ist das Einfügen. Wenn Sie ihn dann ziemlich hoch einstellen, ist es sinnvoll, ihn auf etwa 0,9 zu erhöhen. Das Schlimmste, was passieren wird, ist, dass Sie etwas häufiger schreiben, als Sie es sonst benötigen würden, aber die Auswirkungen auf Checkpoints werden erheblich reduziert.

24
Scott Marlowe

In einem sehr "schreibintensiven" System sind Sie wahrscheinlich durch die Rate begrenzt, mit der WAL während der Spitzenaktivität geschrieben werden kann.

Wenn Sie wirklich akzeptieren können, dass bei einem Fehler einige aktuelle Daten verloren gehen, können Sie synchrones Festschreiben deaktivieren.

kann eine nützliche Alternative sein, wenn die Leistung wichtiger ist als die genaue Gewissheit über die Dauerhaftigkeit einer Transaktion

Wenn Sie Ihre Hardware ändern können, können Sie Folgendes in Betracht ziehen, um Schreibvorgänge zu optimieren:

  • RAID10 über RAID5
  • Viele Spindeln (könnte beispielsweise 2,5 "statt 3,5" bedeuten)
  • SAS über SATA
  • 15K über 10K Laufwerke
  • SSD

--bearbeiten

Basierend auf Ihrem Kommentar zu @ Scotts ausgezeichnete Antwort : "Das Schreibvolumen ist tatsächlich fast vollständig einheitlich" und der implizierten Datenrate von "50 KByte pro Sekunde" bezweifle ich, dass Sie etwas tun müssen, das Daten gefährdet Verlust. Vielleicht wäre es hilfreich zu wissen, auf welche Ihrer anderen Konfigurationsparameter eingestellt ist.

Sie können auch die Häufigkeit/Größe Ihrer Commits überprüfen: Ich bin kürzlich auf ein Problem gestoßen, bei dem ich versucht habe,> 1 Million Datensätze in einer einzigen Transaktion zu aktualisieren. Ich habe Protokollnachrichten erhalten, die den von OP beschriebenen ähnlich sind, aber die Transaktion konnte auch nach einigen Stunden nicht abgeschlossen werden. Als ich das Schreiben in mehrere kleinere Transaktionen aufteilte (etwa 10.000 Datensätze), verringerte sich die Gesamtzeit auf etwa 15 Minuten.

Was ich denke passiert ist, war, dass Postgres so viel Zeit damit verbracht hat, die Protokolle zu schreiben, dass checkpoint_timeout verstrichen, bevor wesentliche Fortschritte beim Speichern der Aufzeichnungen erzielt werden konnten. Ich bin mir nicht sicher, ob diese Erklärung zutrifft. Ich erhalte immer noch die Warnungen, aber alle Schreibvorgänge werden schließlich verarbeitet. Ich brauchte (und fand) jedoch eher eine programmatische Problemumgehung als eine, die eine Neukonfiguration der Datenbank erfordert.

Siehe auch http://www.postgresql.org/docs/9.3/static/wal-configuration.html

5
Sarah Messer