Die Übersetzung des Artikels wurde speziell für die Studierenden des Kurses erstellt . Interessiert an einer Weiterentwicklung in diesem Bereich? Wir laden Sie ein zu , an dem wir ausführlich über das Programm, die Besonderheiten des Online-Formats, die Kompetenzen und die Karrieremöglichkeiten sprechen, die Absolventen nach dem Studium erwarten.

PostgreSQL und Einstellungen zur Konsistenz von Aufzeichnungen für jede einzelne Verbindung.
In Compose haben wir es mit vielen Datenbanken zu tun, was uns die Möglichkeit gibt, ihre Funktionalität und Schwächen näher kennenzulernen. Während wir beginnen, die funktionalen Merkmale neuer Datenbanken zu schätzen, denken wir manchmal, dass es gut wäre, wenn solche Funktionen auch in älteren Werkzeugen vorhanden wären, mit denen wir schon lange arbeiten. Eine der neuen Funktionen, die wir in PostgreSQL sehen wollten, war die anpassbare Schreibkonsistenz pro Verbindung im gesamten Cluster. Und wie sich herausstellte, haben wir sie bereits, und heute wollen wir Ihnen Informationen darüber geben, wie Sie sie nutzen können.
Warum brauche ich das?
Das Verhalten eines Clusters hängt von Ihrer Anwendung ab. Nehmen wir beispielsweise eine Anwendung zur Rechnungszahlung. Sie benötigen eine hundertprozentige Konsistenz im Cluster, daher müssen Sie synchrone Commits aktivieren, damit Ihre Datenbank auf alle Änderungen wartet. Wenn Ihre Anwendung jedoch ein schnell wachsendes soziales Netzwerk ist, ziehen Sie sicherlich eine schnelle Reaktionszeit der hundertprozentigen Konsistenz vor. Um dies zu erreichen, können Sie in Ihrem Cluster asynchrone Commits verwenden.
Lernen Sie den Kompromiss kennen
Sie müssen einen Kompromiss zwischen Datenkonsistenz und Leistung eingehen. PostgreSQL tendiert zur Konsistenz, da die Standardkonfiguration in diesem Fall vorhersehbar ist und keine unerwarteten Überraschungen mit sich bringt. Lassen Sie uns nun die Kompromisse kennenlernen.
Kompromiss 1: Leistung
Wenn der PostgreSQL-Cluster keine Konsistenz benötigt, kann er durchaus asynchron arbeiten. Die Aufzeichnung erfolgt auf dem Cluster-Leiter, und seine Replikate erhalten nach wenigen Millisekunden die Aktualisierungen. Wenn der PostgreSQL-Cluster Konsistenz benötigt, muss er synchron arbeiten. Die Aufzeichnung wird beim Cluster-Leiter durchgeführt, der die Aktualisierung an die Replikate sendet und die Bestätigung abwartet, dass jede Replik die Aufzeichnung durchgeführt hat, bevor sie die Bestätigung an den Client sendet, der die Aufzeichnung initiiert hat, dass diese erfolgreich war. Der praktische Unterschied zwischen diesen Ansätzen besteht darin, dass die asynchrone Methode zwei Netzwerk-Hops erfordert, während die synchrone vier erfordert.
Kompromiss 2: Konsistenz
Das Ergebnis im Falle eines Ausfalls des Leiters in diesen beiden Ansätzen wird ebenfalls unterschiedlich sein. Wenn die Arbeit asynchron ausgeführt wird, werden bei einem solchen Fehler nicht alle Aufzeichnungen von den Replikaten erfasst. Wie viel geht verloren? Das hängt von der Anwendung selbst und der Effizienz der Replikation ab. Mit der Compose-Replikation wird ein Replikat daran gehindert, Leiter zu werden, wenn die Menge an Informationen darin 1 MB kleiner ist als die des Leiters, was bedeutet, dass beim asynchronen Betrieb potenziell bis zu 1 MB an Aufzeichnungen verloren gehen kann.
Im synchronen Modus geschieht dies nicht. Wenn der Leiter ausfällt, werden alle Replikate aktualisiert, da jede Aufzeichnung, die auf dem Leiter bestätigt wurde, auch in den Replikaten bestätigt werden muss. Das ist die Konsistenz.
Das synchrone Verhalten macht Sinn in Anwendungen zur Zahlung von Rechnungen, wo Konsistenz einen klaren Vorteil bei der Suche nach einem Kompromiss zwischen Konsistenz und Leistung bietet. Das Wichtigste für eine solche Anwendung sind gültige Daten. Denken Sie nun an ein soziales Netzwerk, in dem die Hauptaufgabe darin besteht, die Aufmerksamkeit der Benutzer zu halten, indem Anfragen so schnell wie möglich beantwortet werden. In diesem Fall hat die Leistung mit weniger Netzwerk-Hops und kürzerer Wartezeit auf Bestätigungen Priorität. Der Kompromiss zwischen Leistung und Konsistenz ist jedoch nicht der einzige, über den man nachdenken muss.
Kompromiss 3: Ausfälle
Es ist sehr wichtig zu verstehen, wie sich ein Cluster während eines Fehlers verhält. Lassen Sie uns die Situation betrachten, in der eine oder mehrere Repliken ausfallen. Wenn die Commits asynchron verarbeitet werden, wird der Leader weiterhin funktionieren, d.h. er wird Aufzeichnungen empfangen und bearbeiten, ohne auf fehlende Repliken zu warten. Wenn die Repliken zurück ins Cluster kommen, holen sie den Leader ein. Bei synchroner Replikation, wenn Repliken nicht antworten, hat der Leader keine Wahl und wird weiterhin auf die Bestätigung des Commits warten, bis die Replik ins Cluster zurückkehrt und die Aufzeichnung annehmen und bestätigen kann.
Eine Verbindung pro Transaktion?
Jede Anwendung benötigt eine spezielle Kombination aus Konsistenz und Leistung. Es sei denn, es handelt sich um unsere Rechnungsanwendung, die wir uns als vollständig konsistent vorstellen, oder um unsere fast flüchtige Social-Media-Anwendung. In allen anderen Fällen gibt es Momente, in denen einige Operationen synchron und andere asynchron sein müssen. Sie möchten vielleicht nicht, dass das System wartet, bis eine Nachricht im Chat committet wurde, aber wenn in derselben Anwendung eine Zahlung durchgeführt wird, wird man warten müssen.
All diese Entscheidungen trifft natürlich der Anwendungsentwickler. Die richtigen Entscheidungen darüber, wann welcher Ansatz angewendet werden soll, helfen, das Beste aus dem Cluster herauszuholen. Es ist wichtig, dass der Entwickler zwischen ihnen auf SQL-Ebene für Verbindungen und für Transaktionen wechseln kann.
Praktische Sicherstellung der Kontrolle
Standardmäßig sorgt PostgreSQL für Konsistenz. Dies wird durch den Serverparameter synchronous_commitkontrolliert. Standardmäßig ist er auf oneingestellt, hat jedoch drei andere Optionen: local, remote_write oder off.
Wenn der Parameter auf eingestellt ist, werden alle synchronen Commits gestoppt, selbst im lokalen System. Der Parameter in local definiert den synchronen Modus für das lokale System, die Aufzeichnungen in Repliken erfolgen jedoch asynchron. off Remote_write geht noch weiter: Aufzeichnungen in Repliken erfolgen asynchron, aber es wird zurückgegeben, wenn die Replik die Aufzeichnung angenommen hat, diese jedoch nicht auf die Festplatte geschrieben hat. Wenn wir den verfügbaren Bereich an Optionen betrachten, wählen wir das Verhalten und, da wir uns bewusst sind, dass
es sich um synchrone Aufzeichnungen handelt, wählen wir on für asynchrone Commits über das Netzwerk, während wir die lokalen Commits synchron lassen. local für asynchrone Commits über das Netzwerk und lassen dabei lokale Commits synchron.
Jetzt zeigen wir Ihnen, wie Sie dies im Handumdrehen einstellen können, aber stellen Sie sich vor, dass wir es für den Server installiert haben. synchronous_commit in local Wir haben uns gefragt, ob man den Parameter synchronous_commit zur Laufzeit ändern kann, und es stellte sich heraus, dass es nicht nur möglich ist, dafür gibt es sogar zwei Methoden. Die erste besteht darin, die Sitzung Ihrer Verbindung wie folgt einzustellen:
SET SESSION synchronous_commit TO ON;
// Ihre Schreibvorgänge kommen hierhinAlle nachfolgenden Schreibvorgänge in der Sitzung bestätigen die Schreiboperationen für die Replikate, bevor sie das positive Ergebnis an den verbundenen Client zurückgeben. Es sei denn, Sie ändern die Einstellung synchronous_commit wieder. Sie können den Teil SESSION im Befehl weglassen, da er den Standardwert haben wird.
Die zweite Methode ist nützlich, wenn Sie einfach sicherstellen möchten, dass Sie für eine Transaktion die synchrone Replikation erhalten. In vielen NoSQL-Datenbanken gibt es kein Konzept von Transaktionen, aber in PostgreSQL gibt es das. In diesem Fall starten Sie eine Transaktion und stellen dann synchronous_commit in on vor der Ausführung des Schreibvorgangs für die Transaktion ein. COMMIT wird die Transaktion festschreiben, indem es jeden Wert des Parameters verwendet, der zu diesem Zeitpunkt gesetzt war, obwohl es am besten ist, die Variable im Voraus zu setzen, damit andere Entwickler verstehen, dass die Aufzeichnungen nicht asynchron sind. synchronous_commitBEGIN; SET LOCAL synchronous_commit TO ON; // Ihre Schreibvorgänge kommen hierhin COMMIT;
Alle Commit-Transaktionen werden jetzt bestätigt, wie in Replikate geschrieben, bevor die Datenbank eine positive Antwort an den verbundenen Client zurückgibt. PostgreSQL konfigurieren
Vorher haben wir uns ein System von PostgreSQL mit
Wir haben uns ein PostgreSQL-System mit synchronous_commit, das in local, vorgestellt. Damit dies auf der Serverseite real ist, müssen Sie zwei Konfigurationsparameter des Servers festlegen. Ein weiterer Parameter synchronous_standby_names wird wirksam, wenn synchronous_commit in on. Er definiert, welche Replikate das Recht auf synchrone Commits haben, und wir werden ihn auf *setzen, was bedeutet, dass alle Replikate aktiviert werden. Diese Werte werden normalerweise in durch Hinzufügen von:
synchronous_commit = local
synchronous_standby_names='*'Indem wir den Parameter synchronous_commit auf den Wert localsetzen, schaffen wir ein System, in dem lokale Festplatten synchron bleiben, während die Commits von Netzwerkreplikaten standardmäßig asynchron sind. Es sei denn, wir entscheiden uns, diese Commits synchron zu gestalten, wie oben gezeigt.
Wenn Sie die Entwicklung des , Sie haben möglicherweise einige kürzliche Änderungen bemerkt (, ), die es den Benutzern von Governor ermöglichen, diese Einstellungen zu testen und ihre Konsistenz zu steuern.
Noch ein paar Worte…
Vor einer Woche hätte ich Ihnen gesagt, dass es unmöglich ist, PostgreSQL so fein abzustimmen. Genau dann bestand Kurt, ein Mitglied des Compose-Plattformteams, darauf, dass es diese Möglichkeit gibt. Er besänftigte meine Bedenken und fand in der Dokumentation von PostgreSQL :

Dieser Parameter kann jederzeit geändert werden. Das Verhalten für jede Transaktion wird durch die Einstellung definiert, die zum Zeitpunkt des Commits aktiv ist. Daher ist es möglich und nützlich, dass einige Transaktionen synchronen Commits durchführen, während andere asynchron sind. Um beispielsweise eine multistatement Transaktion dazu zu bringen, Commits asynchron durchzuführen, wenn der Standardwert entgegengesetzt ist, setzen Sie bitte SET LOCAL synchronous_commit TO OFF in der Transaktion.
Mit dieser kleinen Modifikation in der Konfigurationsdatei haben wir den Benutzern die Möglichkeit gegeben, ihre Konsistenz und Leistung zu steuern.
Quelle: habr.com
