Die kurze Antwort lautet "Versuch und Irrtum, geleitet von Überwachungs- und Leistungsmetriken".
Es gibt einige allgemeine Faustregeln, die Ihnen helfen sollen, den vagen Bereich zu finden, in dem Sie beginnen sollten, aber sie sind sehr allgemein. Die allgemeinen Richtlinien "Anzahl der CPUs plus Anzahl der unabhängigen Festplatten" werden oft zitiert, sind jedoch nur ein sehr grober Ausgangspunkt.
Was Sie wirklich tun müssen, ist eine zuverlässige Leistungsmessung für Ihre Anwendung. Starten Sie die Aufzeichnung von Statistiken.
Hierfür gibt es nicht viel integriertes Werkzeug. Es gibt Dinge wie das Nagios- check_postgres
Skript, die Leistungsindikatorprotokollierung für Cacti-Systeme, den PostgreSQL-Statistikkollektor usw., aber es gibt nicht viel, das alles zusammenfügt. Leider musst du das selbst tun. Informationen zur PostgreSQL-Seite finden Sie unter Überwachung im PostgreSQL-Handbuch. Es gibt einige Optionen von Drittanbietern, z. B. den Postgres Enterprise Monitor von EnterpriseDB .
Für die hier genannten Metriken auf Anwendungsebene möchten Sie sie in gemeinsam genutzten Datenstrukturen oder in einer externen, nicht dauerhaften Datenbank wie Redis aufzeichnen und entweder beim Aufzeichnen oder vor dem Schreiben in Ihre PostgreSQL-Datenbank aggregieren. Der Versuch, direkt in Pg zu protokollieren, verzerrt Ihre Messungen mit dem durch die Aufzeichnung der Messungen verursachten Overhead und verschlimmert das Problem.
Die einfachste Option ist wahrscheinlich ein Singleton auf jedem App-Server, mit dem Sie Anwendungsstatistiken aufzeichnen. Sie möchten wahrscheinlich eine ständige Aktualisierung von min, max, n, total und mean durchführen. Auf diese Weise müssen Sie nicht jeden Statistikpunkt speichern, sondern nur die Aggregate. Dieser Singleton kann seine Gesamtstatistik alle x Minuten in Pg schreiben. Dies ist so niedrig, dass die Auswirkungen auf die Leistung minimal sind.
Beginnen mit:
Wie hoch ist die Anforderungslatenz? Mit anderen Worten, wie lange dauert es, bis die App eine Anfrage vom Client erhält, bis sie auf den Client antwortet. Erfassen Sie dies über einen Zeitraum hinweg und nicht als einzelne Aufzeichnungen. Gruppieren Sie es nach Anfragetyp. sagen wir, pro Seite.
Wie lange dauert der Datenbankzugriff für jede Abfrage oder jeden Abfragetyp, den die App ausführt? Wie lange dauert es, bis der DB Informationen abruft / speichert, bis er fertig ist und mit der nächsten Aufgabe fortfahren kann? Aggregieren Sie diese Statistiken erneut in der Anwendung und schreiben Sie nur die aggregierten Informationen in die Datenbank.
Wie ist Ihr Durchsatz? Wie viele Abfragen jeder Hauptklasse, die Ihre App ausführt, werden in x Minuten von der DB bearbeitet?
Wie viele Kundenanfragen gab es für denselben Zeitraum von x Minuten?
Wie viele DB-Verbindungen gab es, die alle paar Sekunden abgetastet und über dieselben x-Minuten-Fenster in der DB aggregiert wurden? Wie viele von ihnen waren untätig? Wie viele waren aktiv? In Beilagen? Aktualisierung? wählt? löscht? Wie viele Transaktionen gab es in diesem Zeitraum? Siehe die Dokumentation zum Statistikkollektor
Wie waren die Leistungsmetriken des Host-Systems, die wiederum über dasselbe Zeitintervall abgetastet und aggregiert wurden? Wie viele Lese- und wie viele Schreibzugriffe pro Sekunde? Megabyte pro Sekunde beim Lesen und Schreiben von Datenträgern? CPU-Auslastung? Durchschnittslast? RAM verbrauchen?
Sie können sich jetzt über die Leistung Ihrer App informieren, indem Sie die Daten korrelieren, grafisch darstellen usw. Sie sehen allmählich Muster und stellen Engpässe fest.
Möglicherweise stellen Sie fest, dass Ihr System überlastet ist INSERT
und UPDATE
hohe Transaktionsraten aufweist, obwohl die Datenträger-E / A in Megabyte pro Sekunde recht niedrig sind. Dies ist ein Hinweis darauf, dass Sie die Leistung beim Leeren der Festplatte mit einem akkugepufferten Write-Back-Caching-RAID-Controller oder einigen hochwertigen stromgeschützten SSDs verbessern müssen. Sie können auch verwenden, synchronous_commit = off
wenn es in Ordnung ist, einige Transaktionen bei einem Serverabsturz zu verlieren und / oder einen commit_delay
Teil der Synchronisierungslast zu entlasten.
Wenn Sie Ihre Transaktionen pro Sekunde in Abhängigkeit von der Anzahl der gleichzeitigen Verbindungen grafisch darstellen und die unterschiedliche Anforderungsrate der Anwendung berücksichtigen, können Sie besser erkennen, wo sich Ihr Durchsatz-Sweetspot befindet.
Wenn Sie keinen Fast-Flush-Speicher haben (BBU-RAID oder schnelle, langlebige SSDs), möchten Sie nicht mehr als eine relativ kleine Anzahl von aktiven Verbindungen, möglicherweise höchstens das Doppelte der Anzahl der Festplatten, die Sie haben, wahrscheinlich weniger, je nach RAID-Anordnung , Festplattenleistung usw. In diesem Fall ist es nicht einmal einen Versuch wert. Aktualisieren Sie einfach Ihr Speichersubsystem auf eines mit schneller Datenträgerspülung .
Suchen Sie pg_test_fsync
nach einem Tool, mit dem Sie feststellen können, ob dies ein Problem für Sie darstellt. Die meisten PostgreSQL-Pakete installieren dieses Tool als Teil von contrib, sodass Sie es nicht kompilieren müssen. Wenn Sie weniger als ein paar Tausend Operationen pro Sekunde ausführen, müssen pg_test_fsync
Sie Ihr Speichersystem dringend aktualisieren. Mein mit SSD ausgestatteter Laptop bekommt 5000-7000. Mein - Arbeitsplatz bei der Arbeit mit einem 4-Platten RAID 10 - Array von 7200rpm SATA Platten und Write-Through (Nicht-Schreib-Caching) erhält etwa 80 ops / Sekunde in f_datasync
, auf 20 ops / Sekunde fsync()
; es ist hunderte Male langsamer . Vergleichen Sie : Laptop mit ssd vs Workstation mit Write-Through (Nicht-Schreib-Caching) RAID 10. Die SSD dieses Laptops ist billig und ich vertraue nicht unbedingt darauf, dass der Schreibcache bei Stromausfall geleert wird. Ich behalte gute Backups und würde sie nicht für Daten verwenden, die mir wichtig sind. Gute SSDs arbeiten genauso gut, wenn nicht sogar besser und sind beschreibbar.
Im Falle Ihrer Bewerbung rate ich Ihnen dringend, Folgendes zu prüfen:
- Ein gutes Speichersubsystem mit schnellen Spülvorgängen. Ich kann das nicht genug betonen. Hochwertige stromausfallsichere SSDs und / oder ein RAID-Controller mit stromgeschütztem Write-Back-Cache.
- Wenn Sie
UNLOGGED
Tabellen für Daten verwenden, können Sie es sich leisten, zu verlieren. Aggregieren Sie es regelmäßig in protokollierten Tabellen. Führen Sie beispielsweise Spiele in nicht protokollierten Tabellen fort und schreiben Sie die Ergebnisse in normale dauerhafte Tabellen.
- Verwenden von a
commit_delay
(weniger nützlich bei schnell spülendem Speicher - Hinweis)
- Deaktivieren
synchronous_commit
für Transaktionen, die Sie sich leisten können, um zu verlieren (weniger nützlich bei schnellem Löschen von Speichern - Hinweis Hinweis)
- Partitionierungstabellen, insbesondere Tabellen, in denen Daten "veralten" und bereinigt werden. Löschen Sie eine Partition, anstatt sie aus einer partitionierten Tabelle zu löschen.
- Teilindizes
- Reduzieren Sie die Anzahl der von Ihnen erstellten Indizes. Jeder Index hat Schreibkosten.
- Stapelverarbeitung in größere Transaktionen
- Verwenden schreibgeschützter Hot-Standby-Replikate, um die Leselast von der Hauptdatenbank zu entlasten
- Verwenden einer Caching-Ebene wie memcached oder redis für Daten, die sich seltener ändern oder die es sich leisten können, veraltet zu sein. Sie können
LISTEN
und verwenden NOTIFY
, um die Cache-Invalidierung mithilfe von Triggern für PostgreSQL-Tabellen durchzuführen.
Im Zweifelsfall: http://www.postgresql.org/support/professional_support/
synchronous_commit = off
oder acommit_delay
?