Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Entschlüsselung des Berichts von 2015 von Ilja Kosmodemjanskij "Linux-Tuning zur Verbesserung der PostgreSQL-Leistung"

Haftungsausschluss: Ich möchte darauf hinweisen, dass dieser Bericht auf November 2015 datiert ist – es sind über 4 Jahre vergangen und viel Zeit ist vergangen. Die im Bericht behandelte Version 9.4 wird nicht mehr unterstützt. In den vergangenen 4 Jahren sind 5 neue Versionen von PostgreSQL und 15 Versionen des Linux-Kernels erschienen. Wenn wir diese Stellen neu schreiben, wird am Ende ein anderer Bericht entstehen. Aber hier wird das grundlegende Tuning von Linux für PostgreSQL behandelt, das auch jetzt noch relevant ist.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky


Video abspielen

Mein Name ist Ilja Kosmodemjanskij. Ich arbeite bei PostgreSQL-Consulting. Und jetzt werde ich ein wenig darüber erzählen, was man mit Linux im Allgemeinen in Bezug auf Datenbanken und speziell auf PostgreSQL tun kann, da die Prinzipien ziemlich ähnlich sind.

Worüber werden wir sprechen? Wenn Sie mit PostgreSQL kommunizieren, müssen Sie bis zu einem gewissen Grad ein UNIX-Administrator sein. Was bedeutet das? Wenn wir Oracle und PostgreSQL vergleichen, müssen Sie bei Oracle zu 80 % als DBA im Datenbankmanagement und zu 20 % als Linux-Administrator arbeiten.

Mit PostgreSQL ist es etwas komplizierter. Mit PostgreSQL muss man viel besser verstehen, wie Linux funktioniert. Und dabei muss man ein bisschen hinterherlaufen, denn in letzter Zeit wird alles ziemlich rasch aktualisiert. Neue Kernels erscheinen, neue Funktionen werden eingeführt, die Leistung verbessert sich usw.

Warum sprechen wir über Linux? Nicht, weil wir auf einer Linux-Konferenz in St. Petersburg sind, sondern weil Linux unter den modernen Bedingungen eines der am besten geeigneten Betriebssysteme für den Einsatz mit Datenbanken im Allgemeinen und mit PostgreSQL im Besonderen ist. Denn FreeBSD entwickelt sich leider in eine sehr seltsame Richtung. Und es werden sowohl Leistungsprobleme als auch viele andere Probleme auftreten. Die Leistung von PostgreSQL unter Windows ist überhaupt ein separates, schwieriges Thema, da es unter Windows keinen gemeinsamen Speicher wie unter UNIX gibt, und PostgreSQL von diesem abhängt, da es sich um ein multiprozessuales System handelt.

Und Exoten wie Solaris interessieren, glaube ich, die wenigsten, also legen wir los.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Ein modernes Linux-Distribution hat über 1.000 syctl-Parameter, je nachdem, wie der Kernel zusammengestellt wird. Wenn wir uns zusätzlich verschiedene Anleitungen ansehen, gibt es viele weitere Möglichkeiten, etwas anzupassen. Es gibt Parameter für Dateisysteme und wie man sie mountet. Wenn es Fragen gibt, wie man es startet: was im BIOS aktiviert werden muss, wie die Hardware konfiguriert werden muss usw.

Das ist ein sehr umfangreiches Thema, über das man mehrere Tage sprechen kann und nicht nur in einem kurzen Vortrag, aber ich werde mich jetzt auf wichtige Punkte konzentrieren, wie man die Fallstricke vermeiden kann, die garantiert verhindern, dass Sie die Datenbank unter Linux gut nutzen können, wenn Sie sie nicht anpassen. Ein wichtiger Punkt ist, dass viele Parameter standardmäßig nicht in den richtigen Einstellungen für die Datenbank enthalten sind. Das bedeutet, dass die Funktionalität von Anfang an schlecht oder gar nicht funktioniert.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Welche traditionellen Tuning-Ziele gibt es in Linux? Ich denke, dass es, da Sie alle mit der Verwaltung von Linux zu tun haben, nicht nötig ist zu erklären, was Ziele sind.

Es kann optimiert werden:

  • CPU.
  • Speicher.
  • Speicherplatz.
  • Sonstiges. Darüber werden wir am Ende als Leckerbissen sprechen. Selbst solche Parameter wie die Energiesparpolitik können die Leistung ganz unvorhersehbar und nicht unbedingt erfreulich beeinflussen.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was ist das Besondere an PostgreSQL und Datenbanken im Allgemeinen? Das Problem ist, dass man nicht einfach einen einzelnen Riegel optimieren und sehen kann, dass die Leistung sich erheblich verbessert hat.

Ja, es gibt solche Riegel, aber eine Datenbank ist ein komplexes Gebilde. Sie interagiert mit allen Ressourcen, die der Server hat, und zieht es vor, vollständig zu interagieren. Wenn Sie sich die aktuellen Empfehlungen von Oracle ansehen, wie man das Host-Betriebssystem nutzen sollte, dann ist das wie der Witz über den mongolischen Kosmonauten – die Hunde füttern und nichts anfassen. Geben wir der Datenbank alle Ressourcen, die Datenbank regelt alles selbst.

Prinzipiell ist die Situation bei PostgreSQL genau dieselbe. Der Unterschied besteht darin, dass die Datenbank nicht alle Ressourcen selbst abrufen kann, d. h. dass man manchmal auf Linux-Ebene selbst Hand anlegen muss.

Die Hauptidee ist nicht, ein einzelnes Ziel auszuwählen und damit zu beginnen, es zu optimieren, zum Beispiel Speicher, CPU oder Ähnliches, sondern das Arbeitspensum zu analysieren und zu versuchen, die Durchsatzrate maximal zu verbessern, damit die Last, die die freundlichen Programmierer für uns geschaffen haben, einschließlich unserer Benutzer, möglichst effizient durch unsere Datenbank verarbeitet wird.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Das ist ein Bild zur Erklärung, was das ist. Es gibt einen Buffer im Linux-Betriebssystem, es gibt Shared Memory und Shared Buffers in PostgreSQL. Im Gegensatz zu Oracle arbeitet PostgreSQL direkt nur über den Kernel-Buffer, d. h. damit eine Seite von der Festplatte in seinen Shared Memory gelangt, muss sie durch den Kernel-Buffer gehen, und die Situation ist genau dieselbe.

Unter diesem System leben die Festplatten. Ich habe es als Festplatten gezeichnet. Tatsächlich kann dort ein RAID-Controller sein usw.

Und dieser Ein- und Ausgabeprozess erfolgt mehr oder weniger durch dieses Element.

PostgreSQL ist eine klassische Datenbank. Im Inneren gibt es Seiten. Der gesamte Ein- und Ausgabestrom erfolgt über diese Seiten. Wir laden mit Seiten Blöcke in den Speicher. Und wenn nichts passiert ist, sondern wir sie einfach gelesen haben, verschwinden sie allmählich aus dem Cache, aus den Shared Buffern, und gelangen zurück auf die Festplatte.

Wenn wir irgendwo etwas ersetzt haben, wird die gesamte Seite als schmutzig markiert. Ich habe sie hier mit blauer Farbe markiert. Und das bedeutet, dass diese Seite mit dem Blockspeicher synchronisiert werden muss. D. h. als wir sie schmutzig gemacht haben, haben wir einen Eintrag in WAL gemacht. Und zu einem bestimmten Zeitpunkt trat ein Phänomen namens Checkpoint auf. Und in dieses Protokoll wurde die Information darüber geschrieben, dass es eingetreten ist. Und das bedeutet, dass alle schmutzigen Seiten, die zu diesem Zeitpunkt in diesen Shared Buffern waren, mit dem Speichermedium über fsync durch den Kernel-Buffer synchronisiert wurden.

Warum geschieht das? Wenn der Strom ausfällt, haben wir nicht das Problem, dass alle Daten verschwunden sind. Der persistente Speicher, von dem uns alle erzählt haben, ist derzeit in der Theorie der Datenbanken – die strahlende Zukunft, auf die wir natürlich hinarbeiten und die uns gefällt, aber vorerst leben wir noch 20 Jahre hinterher. Und wir müssen natürlich darauf achten.

Die Aufgabe, die Durchsatzkapazität zu maximieren, besteht darin, alle diese Schritte zu optimieren, damit alles schnell hin und her geht. Shared Memory ist hauptsächlich ein Seiten-Cache. In PostgreSQL haben wir eine Anfrage gesendet, um etwas auszuwählen, er hat diese Daten von der Festplatte abgerufen. Sie sind in die Shared Buffer gelangt. Damit das besser funktioniert, sollte viel Speicher vorhanden sein.

Damit alles gut und schnell funktioniert, müssen Sie das Betriebssystem in allen Phasen richtig einrichten. Wählen Sie ausgewogenes Hardware, denn wenn irgendwo ein Ungleichgewicht besteht, können Sie zwar viel Arbeitsspeicher haben, aber dieser wird mit unzureichender Geschwindigkeit bedient.

Und wir werden jeden dieser Punkte durchgehen.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Damit diese Seiten schneller hin und her reisen, müssen wir Folgendes erreichen:

  • Erstens muss der Umgang mit dem Arbeitsspeicher effizienter sein.
  • Zweitens sollte dieser Übergang, wenn Seiten aus dem Speicher auf die Festplatte gelangen, effizienter sein.
  • Und drittens sollten die Festplatten gut sein.

Wenn Sie 512 GB RAM haben in Server und das alles am Ende auf eine SATA-Festplatte ohne Cache ankommt, verwandelt sich der gesamte Datenbankserver nicht nur in einen Kürbis, sondern in einen Kürbis mit SATA-Schnittstelle. Sie werden direkt darauf stoßen. Nichts wird Sie retten.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was den ersten Punkt über den Arbeitsspeicher betrifft, so gibt es drei Dinge, die das Leben erheblich erschweren können.

Das erste ist NUMA. NUMA ist ein Konzept, das entwickelt wurde, um die Leistung zu verbessern. Je nach Arbeitslast können verschiedene Dinge optimiert werden. In ihrer aktuellen Form ist sie für Anwendungen wie Datenbanken, die intensiv gemeinsam genutzte Seiten Caches verwenden, nicht sehr gut.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Kurz gesagt. Wie erkennt man, dass mit NUMA etwas nicht stimmt? Sie haben ein unangenehmes Geräusch, plötzlich ist eine CPU überlastet. Gleichzeitig analysieren Sie die Anfragen in PostgreSQL und sehen, dass dort nichts Ähnliches ist. Diese Anfragen sollten die CPU nicht so intensiv beanspruchen. Es kann lange dauern, dies zu erkennen. Am besten verwenden Sie von Anfang an die richtige Empfehlung zur Einrichtung von NUMA für PostgreSQL.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was passiert wirklich? NUMA steht für Non-Uniform Memory Access. Worauf basiert das? Sie haben eine CPU, daneben ist deren lokaler Speicher. Und dieser Interconnects-Speicher kann Speicher von anderen CPUs abrufen.

Wenn Sie ausführen numactl --hardware, erhalten Sie eine große Ausgabe. Unter anderem wird es ein Feld mit Distanzen geben. Dort finden Sie Zahlen – 10-20, etwas in dieser Art. Diese Zahlen sind nichts anderes als die Anzahl der Hops, um diesen entfernten Speicher anzuschließen und lokal zu nutzen. Im Prinzip ist das eine gute Idee. Es beschleunigt die Leistung bei bestimmten Lasten erheblich.

Stellen Sie sich jetzt vor, Sie haben eine CPU, die zunächst versucht, ihren lokalen Speicher zu nutzen, um dann über das Interconnect einen anderen Speicher für etwas zu abrufen. Und auf diese CPU gelangt der gesamte Page Cache von PostgreSQL – alles, was da sind könnte, einige Gigabyte. Sie erhalten immer den schlechtesten Fall, weil in diesem Modul der Arbeitsspeicher normalerweise wenig Platz hat. Und der gesamte Speicher, der verwaltet wird, läuft über diese Interconnects. Das wird langsam und frustrierend. Und Sie haben einen Prozessor, der diesen Knoten versorgt, der ständig überlastet ist. Und die Zugriffszeit auf diesen Speicher ist schlecht, langsam. Das ist die Situation, die Sie vermeiden möchten, wenn Sie dies für eine Datenbank verwenden.

Daher ist die sinnvollere Lösung für die Datenbank, dass das Betriebssystem Linux überhaupt nicht weiß, was dort passiert. Damit es auf den Speicher zugreift, wie es zugreift.

Warum ist das so? Es scheint, dass es umgekehrt sein sollte. Das passiert aus einem einfachen Grund, dass wir viel Speicher für den Page Cache benötigen – Dutzende, Hunderte von Gigabyte.

Und wenn wir das alles zugewiesen und unsere Daten dort zwischengespeichert haben, dann wird der Vorteil durch die Verwendung des Caches deutlich größer sein als der Vorteil durch so eine raffinierte Speicheransprache. Dadurch gewinnen wir in einem Vergleich dazu, dass wir effizienter auf den Speicher mit NUMA‐Technik zugreifen.

Aus diesem Grund gibt es derzeit zwei Ansätze, solange die strahlende Zukunft noch nicht eingetreten ist und die Datenbank nicht selbst herausfindet, auf welchen CPUs sie arbeitet und woher sie etwas abrufen muss.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Daher ist der richtige Ansatz, NUMA generell abzuschalten, zum Beispiel beim Neustart. In den meisten Fällen sind die Gewinne so erheblich, dass die Frage, was besser ist, gar nicht aufkommt.

Es gibt eine andere Möglichkeit. Wir verwenden sie öfter als die erste, weil es für einen Kunden, der zu uns kommt, ein großes Anliegen ist, den Server neugestartet zu bekommen. Sein Geschäft läuft dort. Und sie haben Probleme mit NUMA. Daher versuchen wir, es auf weniger invasive Weise abzustellen als durch einen Neustart, aber achten Sie darauf, dass es auch tatsächlich abgeschaltet ist. Denn wie die Erfahrung zeigt, dass wir NUMA für den übergeordneten PostgreSQL-Prozess deaktivieren, ist das gut, aber es ist nicht unbedingt sicher, dass das funktioniert. Man muss überprüfen und sicherstellen, dass es wirklich abgeschaltet ist.

Es gibt einen guten Beitrag von Robert Haas. Er ist einer der Committer von PostgreSQL und zählt zu den Hauptentwicklern aller Low-Level-Details. Wenn man den Links in diesem Beitrag folgt, findet man mehrere farbenfrohe Geschichten darüber, wie NUMA den Menschen das Leben erschwert hat. Schaut euch die Checkliste für Systemadministratoren an, um zu sehen, was auf dem Server eingestellt werden muss, damit unsere Datenbank gut funktioniert. Diese Einstellungen sollten notiert und überprüft werden, denn sonst kann es problematisch werden.

Ich weise darauf hin, dass dies alle Einstellungen betrifft, über die ich sprechen werde. Normalerweise werden Datenbanken im Master-Slave-Modus für Ausfallsicherheit konfiguriert. Vergessen Sie nicht, diese Einstellungen auch im Slave vorzunehmen, denn eines schönen Tages wird ein Notfall eintreten, und Sie müssen auf den Slave umschalten, der dann zum Master wird.

In einer Notfallsituation, in der alles schiefgeht, klingelt ständig das Telefon, und der Chef kommt mit einem großen Stock hereingestürzt. Dann bleibt keine Zeit, um zu prüfen. Die Ergebnisse können ziemlich katastrophal sein.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Der nächste Punkt sind Huge Pages. Huge Pages sind schwierig separat zu testen, und es macht auch keinen Sinn, obwohl es Benchmarks gibt, die das können. Diese finden Sie leicht über eine Google-Suche.

Worum geht es? Sie haben einen nicht besonders teuren Server mit viel RAM, zum Beispiel mehr als 30 GB. Huge Pages werden nicht verwendet. Das bedeutet, dass es eindeutig einen Overhead bei der Speichernutzung gibt. Und dieser Overhead ist alles andere als angenehm.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Warum ist das so? Was passiert dabei? Das Betriebssystem weist den Speicher in kleinen Stücken zu. So ist es bequem, das hat sich historisch so entwickelt. Wenn man ins Detail geht, muss das OS virtuelle Adressen in physische übersetzen. Und dieser Prozess ist nicht der einfachste, weshalb das OS das Ergebnis dieses Vorgangs im Translation Lookaside Buffer (TLB) cacht.

Da der TLB ein Cache ist, treten in dieser Situation alle typischen Cache-Probleme auf. Erstens, wenn Sie sehr viel RAM haben und dieser in kleinen Chunks zugewiesen ist, wird der Buffer sehr groß. Und wenn der Cache groß ist, dauert die Suche darin länger. Der Overhead ist erheblich, und er selbst benötigt Platz, d.h. irgendetwas Unangemessenes verbraucht RAM.

Zwei – je mehr der Cache in einer solchen Situation anwächst, desto höher ist die Wahrscheinlichkeit, dass Sie Cache Misses haben. Die Effizienz dieses Caches sinkt schnell mit seiner Größe. Deshalb wurde in Betriebssystemen ein einfacher Ansatz entwickelt. In Linux wird dies schon lange verwendet. In FreeBSD ist es nicht so lange her, dass es eingeführt wurde. Aber wir sprechen von Linux. Es sind huge pages.

Hier ist zu erwähnen, dass huge pages als Idee ursprünglich von Gemeinschaften, zu denen Oracle und IBM gehörten, durchgesetzt wurden, d. h. die Hersteller von Datenbanken haben intensiv darüber nachgedacht, dass dies nützlich sein könnte, unter anderem für Datenbanken.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Wie lässt sich das mit PostgreSQL kombinieren? Erstens müssen huge pages im Linux-Kernel aktiviert sein.

Zweitens müssen sie explizit durch den sysctl-Parameter angegeben werden – wie viele es sind. Die Zahlen stammen von einem älteren Server. Sie können ungefähr berechnen, wie viele Shared Buffers Sie haben, damit die huge pages dort Platz finden.

Wenn Ihr gesamte Server PostgreSQL gewidmet ist, dann ist ein guter Ausgangspunkt, entweder 25 % des Arbeitsspeichers für Shared Buffers zu verwenden oder 75 %, wenn Sie sicher sind, dass Ihre Datenbank in diese 75 % passt. Das ist der erste Ausgangspunkt. Und rechnen Sie, wenn Sie 256 GB RAM haben, dann haben Sie entsprechend 64 GB Shared Buffers. Schätzen Sie ungefähr mit etwas Puffer – in welcher Höhe diese Zahl eingestellt werden sollte.

Bis zur Version 9.2 (wenn ich mich nicht irre, ab Version 8.2) konnte man PostgreSQL mithilfe einer Drittanbieterbibliothek mit huge pages verbinden. Und das muss immer gemacht werden. Erstens muss das Kernel in der Lage sein, huge pages richtig zuzuweisen. Und zweitens, damit die Anwendung, die damit arbeitet, sie nutzen kann. Einfach so wird sie das nicht tun. Da PostgreSQL den Speicher im Style von System 5 zugewiesen hat, konnte dies mit libhugetlbfs geschehen – das ist der vollständige Name der Bibliothek.

In Version 9.3 wurde die Leistung von PostgreSQL im Umgang mit Speicher verbessert, und die Methode 5 zur Speicherzuweisung wurde aufgegeben. Alle waren sehr erfreut, denn ansonsten versucht man, zwei Instanzen von PostgreSQL auf einer Maschine zu starten, und er sagt, dass der Shared-Speicher nicht ausreicht. Und er sagt, man muss den sysctl anpassen. Dabei ist der sysctl so beschaffen, dass man sich auch neu starten muss usw. Insgesamt waren alle erfreut. Aber die mmap-Speicherzuweisung hat die Verwendung von Huge Pages beeinträchtigt. Die meisten unserer Kunden verwenden große Shared Buffers. Und wir haben dringend empfohlen, nicht auf 9.3 umzusteigen, da dort der Overhead in guten Prozentsätzen beginnt zu berechnen.

Aber die Community hat auf dieses Problem hingewiesen und in 9.4 wurde dieses Thema sehr gut überarbeitet. In 9.4 gibt es nun einen Parameter in postgresql.conf, mit dem man try, on oder off aktivieren kann.

Try ist der sicherste Parameter. Beim Start von PostgreSQL, wenn er den Shared-Speicher zuweist, versucht er, sich diesen Speicher aus den Huge Pages zu holen. Und wenn das nicht klappt, fällt er auf die normale Zuweisung zurück. Wenn Sie FreeBSD oder Solaris haben, können Sie try verwenden, das ist immer sicher.

Wenn on, dann startet er einfach nicht, wenn er den Speicher nicht aus den Huge Pages zuweisen konnte. Das hängt dann von den individuellen Vorlieben ab. Aber wenn Sie try eingestellt haben, stellen Sie sicher, dass wirklich das zugewiesen wurde, was benötigt wird, denn es gibt viel Raum für Fehler. Momentan funktioniert diese Funktionalität nur unter Linux.

Noch eine kleine Anmerkung, bevor wir fortfahren. Transparent Huge Pages sind bisher nicht für PostgreSQL relevant. Er kann sie nicht richtig nutzen. Und bei Transparent Huge Pages gibt es für solche Workloads, bei denen ein großer Stück Shared-Speicher benötigt wird, nur bei sehr großen Volumina Vorteile. Wenn Sie Terabytes an Speicher haben, kann das eine Rolle spielen. Wenn wir von alltäglichen Anwendungen sprechen, bei denen Sie 32, 64, 128 oder 256 GB Speicher auf der Maschine haben, dann ist die normale Huge Page-Implementierung in Ordnung, während Transparent einfach deaktiviert bleibt.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Und das letzte Thema, das den Speicher betrifft, ist nicht direkt mit dem Durchsatz verbunden, kann aber das Leben erheblich erschweren. Die gesamte Bandbreite leidet erheblich, da der Server ständig swappt.

Und das wird in einer Reihe von Momenten sehr unangenehm sein. Das Hauptproblem besteht darin, dass sich das Verhalten der modernen Kerne etwas von den älteren Linux-Kernen unterscheidet. Und das ist etwas, auf was man ziemlich unangenehm tritt, denn wenn wir über die Arbeit mit Swap sprechen, endet das nicht mit dem rechtzeitigen Erscheinen des OOM-Killers. Und der OOM-Killer, der nicht rechtzeitig kam und PostgreSQL heruntergefahren hat, ist unangenehm. Das erfahren alle, d. h. bis zum letzten Benutzer.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was passiert? Ihr habt viel Arbeitsspeicher, alles funktioniert gut. Aber aus irgendeinem Grund hängt der Server im Swap und verlangsamt sich dadurch. Es scheint, dass viel Speicher vorhanden ist, aber trotzdem passiert es.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Früher haben wir empfohlen, vm.swappiness auf null zu setzen, d. h. Swap zu deaktivieren. Früher schien es, dass 32 GB Arbeitsspeicher und entsprechende Shared Buffers eine riesige Menge sind. Die Hauptaufgabe von Swap besteht darin, einen Platz zu haben, wohin man einen Prozess ablegen kann, wenn wir ausfallen. Und das hat nicht mehr wirklich funktioniert. Und was macht man dann mit diesem Prozess? Das ist dann so eine Aufgabe, bei der nicht ganz klar ist, wozu Swap überhaupt benötigt wird, erst recht nicht in solcher Größe.

Aber in den moderneren, d. h. in den dritten Versionen des Kerns hat sich das Verhalten geändert. Wenn man Swap auf null setzt, also deaktiviert, wird irgendwann, auch bei noch vorhandenem Arbeitsspeicher, der OOM-Killer kommen, um die intensivsten Verbraucher zu killen. Denn er wird annehmen, dass bei dieser Arbeitslast noch ein wenig Speicher übrig ist und wir ausfallen, d. h. nicht den Systemprozess abschalten, sondern etwas weniger Wichtiges. Dieses weniger Wichtige wird dann ein intensiver Verbraucher des Shared Memory sein, nämlich postmaster. Und danach wird es gut sein, wenn die Datenbank nicht wiederhergestellt werden muss.

Deshalb ist standardmäßig, soweit ich mich erinnere, bei den meisten Distributionen ein Wert von etwa 6 eingestellt, d. h. ab wann mit Swap begonnen wird, je nachdem, wie viel Speicher noch übrig ist. Wir empfehlen jetzt, vm.swappiness auf 1 zu setzen, weil das es praktisch ausschaltet, aber nicht die negativen Effekte hat, die mit einem unerwartet kommenden OOM-Killer verbunden sind, der alles kaputt macht.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was kommt als Nächstes? Wenn wir über die Leistung von Datenbanken sprechen und allmählich zu den Festplatten übergehen, geraten alle in Aufruhr. Denn die Wahrheit, dass die Festplatte langsam und der Speicher schnell ist, ist jedem seit seiner Kindheit bekannt. Und alle wissen, dass es in einer Datenbank Probleme mit der Festplattenleistung geben wird.

Das Hauptproblem mit der Leistung von PostgreSQL, das mit den Spitzenbelastungen bei Checkpoints verbunden ist, entsteht nicht, weil die Festplatte langsam ist. Es liegt eher daran, dass die Bandbreite von Speicher und Festplatte nicht ausgeglichen ist. Dabei können sie an verschiedenen Punkten unausgeglichen sein. PostgreSQL ist nicht konfiguriert, das Betriebssystem ist nicht konfiguriert, die Hardware ist nicht konfiguriert und die Hardware ist falsch. Und dieses Problem tritt nur dann nicht auf, wenn alles nach Plan läuft, d. h. entweder gibt es keine Last oder die Einstellungen und die Hardware sind gut ausgewählt.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was ist das und wie sieht es aus? Normalerweise arbeiten Menschen, die mit PostgreSQL umgehen, mehrmals an diesem Thema. Ich werde es erklären. Wie ich bereits sagte, führt PostgreSQL regelmäßig Checkpoints durch, um die schmutzigen Seiten im gemeinsamen Speicher auf die Festplatte zu dumpen. Wenn wir ein großes Volumen an gemeinsamem Speicher haben, beginnt der Checkpoint intensiv auf die Festplatte einzuwirken, weil er diese Seiten mit fsync dumpet. Er gelangt in den Kernel-Puffer und wird mithilfe von fsync auf die Festplatten geschrieben. Und wenn dieses Volumen groß ist, können wir einen unangenehmen Effekt beobachten, nämlich eine sehr hohe Auslastung der Festplatten.

Hier habe ich zwei Bilder. Ich werde jetzt erklären, was das ist. Das sind zwei zeitlich korrelierte Grafiken. Die erste Grafik zeigt die Festplattenauslastung. Hier erreicht sie in diesem Moment fast 90 %. Wenn Ihre Datenbank mit physischen Festplatten und einem RAID-Controller eine Auslastung von fast 90 % aufweist, sind das schlechte Nachrichten. Das bedeutet, dass es nur noch ein kleines Stückchen bis zu 100 % sind und die Ein- und Ausgabe stoppen werden.

Wenn Sie ein RAID-System haben, sieht die Geschichte ein wenig anders aus. Es hängt davon ab, wie es konfiguriert ist, um was für ein Array es sich handelt usw.

Gleichzeitig ist hier ein Diagramm aus der internen PostgreSQL-Ansicht konfiguriert, das zeigt, wie der Checkpoint abläuft. In Grün wird angezeigt, wie viele Buffer, also diese schmutzigen Seiten, in diesem Moment für die Synchronisierung bei diesem Checkpoint angekommen sind. Und das ist das Wichtigste, was man hier wissen muss. Wir sehen, dass viele Seiten angekommen sind und irgendwann stoßen wir auf die Grenze, d.h. wir haben viel geschrieben, hier ist eindeutig das Speichersystem stark beschäftigt. Und unser Checkpoint hat einen großen Einfluss auf die Festplatte. Idealerweise sollte die Situation eher so aussehen, dass wir hier weniger Schreibvorgänge hatten. Und mit den Einstellungen können wir das beheben, damit es so bleibt. Das heißt, die Auslastung ist gering, aber irgendwo machen wir hier Schreibvorgänge.

Was muss man tun, um dieses Problem zu überwinden? Wenn das IO unter der Datenbank stoppt, bedeutet das, dass alle Benutzer, die ihre Anfragen ausführen wollen, warten müssen.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Wenn man das aus der Sicht von Linux betrachtet, wenn man gute Hardware hat, sie richtig konfiguriert hat und PostgreSQL so eingestellt hat, dass es diese Checkpoints seltener durchführt und sie zeitlich voneinander verteilt, dann landet man bei den Standardparametern von Debian. Für die meisten Linux-Distributionen sieht die Situation so aus: vm.dirty_ratio=20, vm.dirty_background_ratio=10.

Was bedeutet das? Mit dem Kernel 2.6 erschien ein Daemon für das Flushing. Pdglush, je nachdem, wer welchen nutzt, befasst sich mit dem Hintergrund-Entfernen von schmutzigen Seiten aus dem Kernel-Buffer und damit, das Entfernen durchzuführen, wenn es unbedingt nötig ist, wenn das Hintergrund-Entfernen nicht mehr hilft.

Wann tritt das Hintergrund-Entfernen ein? Wenn 10 % des gesamten Arbeitsspeichers, der auf dem Server vorhanden ist, mit schmutzigen Seiten im Kernel-Buffer belegt sind, wird eine spezielle Funktion für das Entfernen im Hintergrund aufgerufen. Warum ist sie im Hintergrund? Sie nimmt als Parameter auf, wie viele Seiten entfernt werden sollen. Und, sagen wir, entfernt N Seiten. Und für eine gewisse Zeit schläft dieses Ding dann. Danach kommt es wieder und entfernt eine weitere Anzahl von Seiten.

Das ist eine ganz einfache Geschichte. Hier ist die Aufgabe wie bei einem Pool, wo in ein Rohr rein und aus einem anderen rausläuft. Unser Checkpoint ist angekommen und wenn er nur wenige schmutzige Seiten zum Entfernen geschickt hat, wird sich das allmählich aus dem Kernel-Buffer durch pgflush zusammensetzen.

Wenn diese schmutzigen Seiten weiter ansammeln, summieren sie sich bis zu 20 %, danach hat das Betriebssystem Priorität, all dies auf die Festplatte zu schreiben, weil die Stromversorgung ausfällt, und es wird schlecht für uns sein. Wir verlieren diese Daten, zum Beispiel.

Was ist der Trick? Der Trick besteht darin, dass diese Parameter in der modernen Welt 20 und 10 % des gesamten Arbeitsspeichers, der im Computer vorhanden ist, ausmachen, was aus Sicht der Bandbreite jeder Festplattensysteme, die Sie haben, völlig tödlich ist.

Stellen Sie sich vor, Sie haben 128 GB RAM. 12,8 GB kommen in Ihr Speichersystem. Und egal, welcher Cache vorhanden ist, egal welches Array Sie haben, sie werden das nicht verkraften.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Deshalb empfehlen wir, diese Zahlen sofort an die Möglichkeiten Ihres RAID-Controllers anzupassen. Hier ist sofort eine Empfehlung für einen Controller angegeben, der 512 MB Cache hat.

Es ist alles sehr einfach. Man kann vm.dirty_background in Bytes setzen. Und diese Einstellungen heben die vorherigen beiden auf. Entweder das Verhältnis standardmäßig oder die aktiviert, die in Bytes sind, werden die arbeiten, die in Bytes sind. Aber da ich als DBA-Berater arbeite und mit verschiedenen Kunden zu tun habe, versuche ich, auf Nummer sicher zu gehen, und daher, wenn in Bytes, dann in Bytes. Niemand hat eine Garantie gegeben, dass ein freundlicher Administrator dem Server nicht mehr Speicher zuschiebt oder ihn nicht neu startet, während die Zahl die gleiche bleibt. Berechnen Sie einfach diese Zahlen, damit garantiert alles hineinpasst.

Was passiert, wenn Sie nicht hineinpassen? Es steht geschrieben, dass jeder Flushing effektiv gestoppt wird, aber in Wirklichkeit ist das eine Floskel. Das Betriebssystem hat ein großes Problem – es hat viele schmutzige Seiten, deshalb wird der IO, der von Ihren Clients erzeugt wird, effektiv gestoppt, d. h. eine SQL-Anwendung ist dabei, eine Anfrage an die Datenbank zu senden, sie wartet. Jeder Input-Output in sie hat die niedrigste Priorität, weil die Datenbank mit dem Checkpoint beschäftigt ist. Und wann sie damit fertig ist, ist völlig unklar. Und wenn Sie nicht am hintergründigen, nicht am Hintergrund-Flushing angekommen sind, bedeutet das, dass alle IO damit beschäftigt sind. Und solange es nicht abgeschlossen ist, können Sie nichts tun.

Es gibt noch zwei wichtige Punkte, die den Rahmen dieses Berichts sprengen. Diese Einstellungen sollten mit den Einstellungen in postgresql.conf übereinstimmen, d. h. den Einstellungen für Checkpoints. Und Ihr Speichersystem sollte angemessen konfiguriert sein. Wenn Sie einen Cache auf RAID haben, sollte sich darauf eine Batterie befinden. Menschen kaufen RAID mit gutem Cache ohne Batterie. Wenn Sie SSDs im RAID haben, sollten sie Server-SSDs sein, sie sollten Kondensatoren haben. Hier ist eine ausführliche Checkliste. Über diesen Link finden Sie meinen Bericht darüber, wie man die Disk-Performance in PostgreSQL einstellt. Dort sind all diese Checklisten enthalten.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Was kann das Leben noch erheblich erschweren? Das sind zwei Parameter. Sie sind relativ neu. Sie können standardmäßig in verschiedenen Anwendungen aktiviert sein. Und sie können das Leben nicht minder komplizieren, wenn sie falsch aktiviert sind.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Es gibt zwei relativ neue Merkmale. Sie sind bereits in den dritten Kernversionen aufgetaucht. Das sind sched_migration_cost in Nanosekunden und sched_autogroup_enabled, das standardmäßig auf eins gesetzt ist.

Und wie beeinträchtigen sie das Leben? Was ist sched_migration_cost? Der Linux-Scheduler kann einen Prozess von einem CPU auf einen anderen migrieren. Und für PostgreSQL, das Abfragen ausführt, ist die Migration auf einen anderen CPU völlig unverständlich. Für die Datenbank ist das sehr schlecht. Daher ist eine sinnvolle Politik, den migration_cost auf einen hohen Wert zu setzen, zumindest mehrere tausend Nanosekunden.

Was wird das für den Scheduler bedeuten? Er wird annehmen, dass dieser Prozess in diesem Zeitraum weiterhin aktiv ist. Das bedeutet, wenn Sie eine lange Transaktion haben, die sich mit etwas Zeitaufwendigem beschäftigt, wird der Scheduler das verstehen. Er wird annehmen, dass dieser Prozess nicht migriert werden muss, solange dieser Timeout nicht überschritten ist. Wenn der Prozess gleichzeitig etwas tut, wird er nicht migriert, sondern läuft weiterhin auf dem CPU, der ihm zugewiesen wurde. Das Ergebnis ist ausgezeichnet.

Der zweite Punkt ist autogroup. Es gibt eine gute Idee für spezifische Workloads, die nichts mit modernen Datenbanken zu tun haben – Prozesse nach dem virtuellen Terminal, von dem aus sie gestartet wurden, zu gruppieren. Das ist praktisch für bestimmte Aufgaben. In der Praxis ist PostgreSQL ein Multiprozesssystem mit Prefork, das von einem Terminal aus gestartet wird. Sie haben Writer-Locks, Checkpoints, und alle Ihre Client-Anfragen werden auf einen Scheduler, auf eine CPU, gruppiert. Dort werden sie gemeinsam warten, bis sie frei werden, um sich gegenseitig zu behindern und sie länger zu besetzen. Diese Situation ist bei solch einer Belastung völlig unnötig, und daher sollte sie abgeschaltet werden.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Mein Kollege Alexey Lesovskiy hat Tests mit einfachem pgbench durchgeführt, bei denen er die Migrationskosten um den Faktor 10 erhöht und die Autogruppe deaktiviert hat. Der Unterschied bei schlechter Hardware betrug fast 10 %.. Es gibt eine Diskussion in der Postgres-Mail-Liste, in der Leute Ergebnisse erwähnen, wie solche Änderungen die Abfragegeschwindigkeit beeinflussten um 50 %.. Es gibt viele solcher Geschichten.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Und abschließend zur Stromsparpolitik. Es ist gut, dass man Linux jetzt auf einem Laptop verwenden kann. Und es wird angeblich den Akku gut schonen. Aber plötzlich stellt sich heraus, dass das auch auf Servern so sein kann.

Darüber hinaus, wenn Sie Server von einem Hosting-Anbieter mieten, kümmern sich die "freundlichen" Hoster nicht darum, Ihnen eine bessere Leistung zu bieten. Ihre Aufgabe ist es, dafür zu sorgen, dass ihre Hardware möglichst effizient genutzt wird. Daher können sie standardmäßig den Energiesparmodus des Laptops im Betriebssystem aktivieren.

Wenn Sie auf einem Server mit einer stark belasteten Datenbank den Energiesparmodus verwenden, dann ist Ihre Wahl acpi_cpufreq + performance. Selbst mit ondemand werden bereits Probleme auftreten.

Intel_pstate ist bereits ein etwas anderer Treiber. Und aktuell wird dieser bevorzugt, da er später entwickelt wurde und besser funktioniert.

Entsprechend ist der Governor ausschließlich performance. Ondemand, powersave und alles andere – das ist nicht für Sie.

Die Ergebnisse von explain analyze in PostgreSQL können um mehrere Größenordnungen abweichen, wenn Sie powersave aktivieren, da der CPU unter Ihrer Datenbank auf vollkommen unvorhersehbare Weise geplant wird.

Diese Dinge können standardmäßig aktiviert sein. Schauen Sie genau hin – haben sie möglicherweise standardmäßig aktiviert. Das könnte wirklich ein großes Problem sein.

Linux-Tuning zur Verbesserung der PostgreSQL-Leistung. Ilya Kosmodemyansky

Und zum Schluss möchte ich den Jungs aus unserem DBA-Team PosgreSQL-Consulting danken, insbesondere Max Boguk und Alexey Lesovsky, die sich jeden Tag mit diesem Thema auseinandersetzen. Für unsere Kunden versuchen wir, es so gut wie möglich zu machen, damit alles funktioniert. Das ist wie mit den Anleitungen zur Flugsicherheit. Hier steht alles in Blut geschrieben. Jede dieser Schrauben wurde im Zuge eines Problems entdeckt. Ich teile sie gerne mit Ihnen.

Fragen:

Danke! Wenn zum Beispiel ein Unternehmen Kosten sparen möchte und die Datenbank und die Anwendungslogik auf einem Server unterbringen möchte, oder wenn das Unternehmen dem Trend zu mikroservicebasierten Architekturen folgt, bei denen PostgreSQL in einem Container läuft. Was ist der Trick dabei? Sysctl beeinflusst global den gesamten Kernel. Ich habe noch nie gehört, dass sysctl irgendwie virtualisiert wird, damit sie in einem Container separat arbeiten. Es gibt nur cgroups und dort gibt es nur eine eingeschränkte Kontrolle. Wie kann man damit leben? Oder wenn Sie Leistung möchten, sollten Sie PostgreSQL auf einem eigenen physischen Server betreiben und diesen optimieren?

Wir haben Ihre Frage auf etwa drei Arten beantwortet. Wenn es sich nicht um einen physischen Server handelt, den man optimieren kann usw., dann entspannen Sie sich, alles wird auch ohne diese Einstellungen gut funktionieren. Wenn Sie eine Last haben, die diese Einstellungen erforderlich macht, werden Sie schneller zu einem physischen Server kommen, als zu diesen Einstellungen.

Was ist das Problem? Wenn es sich um eine virtuelle Maschine handelt, werden Sie wahrscheinlich viele Probleme haben, zum Beispiel mit der insgesamt inkonsistenten Latenz der Festplatte auf den meisten virtuellen Maschinen. Selbst wenn die Festplattendurchsatz gut ist, kann eine fehlgeschlagene Transaktion bei einer Ein- und Ausgabeoperation, die sich zur Zeit eines Checkpoints oder beim Schreiben in WAL ereignet, die mittlere Durchsatzrate kaum beeinflussen, aber die Datenbank wird darunter leiden. Und Sie werden das früher bemerken, als Sie denken.

Wenn Sie NGINX auf demselben Server haben, wird es ebenfalls das gleiche Problem geben. Er wird um den gemeinsamen Speicher kämpfen. Und zu den Problemen, die hier beschrieben sind, werden Sie nicht gelangen.

Aber auf der anderen Seite werden einige dieser Parameter für Sie dennoch relevant sein. Zum Beispiel, mit sysctl den dirty_ratio einstellen, damit es nicht so verrückt ist – das hilft in jedem Fall. So oder so werden Sie mit der Festplatte interagieren. Und das wird nach einem falschen Schema geschehen. Das sind im Grunde die Standardparameter, die ich gezeigt habe. Und in jedem Fall ist es besser, sie zu ändern.

Mit NUMA kann es Probleme geben. VmWare funktioniert zum Beispiel gut mit NUMA mit genau gegenteiligen Einstellungen. Und hier muss man wählen – ein physischer Server oder kein physischer.

Ich habe eine Frage zu Amazon AWS. Sie haben vorgefertigte Images. Eines davon nennt sich Amazon RDS. Gibt es dort irgendwelche benutzerdefinierten Einstellungen für ihr Betriebssystem?

Es gibt Einstellungen, aber das sind andere Einstellungen. Hier konfigurieren wir das Betriebssystem aus der Perspektive, wie die Datenbank dies nutzen wird. Und dort gibt es Parameter, die festlegen, wohin wir jetzt gehen, so eine Art Shaping. D.h. wir brauchen so viele Ressourcen, die werden wir jetzt verbrauchen. Danach fügt Amazon RDS diese Ressourcen hinzu, und die Leistung sinkt. Es gibt verschiedene Geschichten, wie Leute anfangen, in dieser Angelegenheit zu experimentieren. Manchmal sogar sehr erfolgreich. Aber das hat nichts mit den Einstellungen des OS zu tun. Das ist gewissermaßen Cloud-Hacking. Das ist eine andere Geschichte.

Warum haben transparente große Seiten keinen Effekt im Vergleich zu großen TLB?

Haben sie nicht. Man kann das auf viele Arten erklären. Aber faktisch bringen sie einfach nichts. Wie steht es um PostgreSQL? Zu Beginn reserviert es ein großes Stück Shared Memory. Ob transparent oder nicht transparent – das ist völlig unwichtig. Die Tatsache, dass sie zu Beginn reserviert wird, erklärt alles. Und wenn der Speicher sehr groß ist und der shared_memory-Segment umstrukturiert werden muss, dann wird Transparent Huge Pages relevant. Bei PostgreSQL ist es einfach zu Beginn als großes Stück reserviert, und das war's, und danach passiert nichts Besonderes. Natürlich kann man es verwenden, aber es besteht die Gefahr, dass der shared_memory beschädigt wird, wenn er etwas neu zuweist. PostgreSQL weiß jedoch nichts davon.

Quelle: habr.com

60GB SSD 8Gb DDR4