Warum könnte eine halbsynchrone Replikation notwendig sein?

Hallo zusammen. Hier ist Wladislaw Rodin. Momentan unterrichte ich auf dem Portal OTUS Kurse, die sich mit Softwarearchitektur und Hochlast-Softwarearchitektur beschĂ€ftigen. In der Vorbereitungsphase fĂŒr den Start eines neuen Kurses , wo ein erfahrener Spezialist auf diesem Gebiet Ihnen erklĂ€rt, wie Sie handeln sollten, damit der Server nicht mehr abstĂŒrzt. habe ich beschlossen, ein kleines eigenes Material zu schreiben, das ich mit Ihnen teilen möchte.

Warum könnte eine halbsynchrone Replikation notwendig sein?

EinfĂŒhrung

Da auf einer HDD nur etwa 400-700 Operationen pro Sekunde ausgefĂŒhrt werden können (was im Vergleich zu typischen rps, die auf ein hochbelastetes System entfallen, unvorstellbar ist), ist eine klassische Datenbank ein Engpass in der Architektur. Daher ist es notwendig, besondere Aufmerksamkeit den Skalierungsmustern dieses Speichers zu widmen.

Derzeit gibt es 2 Skalierungsmuster fĂŒr die Datenbank: Replikation und Sharding. Sharding ermöglicht es, die Schreiboperation zu skalieren und somit die rps beim Schreiben, die auf einen Server Ihres Clusters entfallen, zu reduzieren. Die Replikation ermöglicht dasselbe, jedoch fĂŒr Leseoperationen. Genau diesem Muster ist dieser Artikel gewidmet.

Replikation

Wenn man sich die Replikation ganz allgemein ansieht, ist es eine einfache Sache: Sie hatten einen Server, auf dem die Daten lagen, und dann konnte dieser Server die Leseanforderungen dieser Daten nicht mehr bewĂ€ltigen. Sie fĂŒgen ein paar Server hinzu, synchronisieren die Daten auf allen Servern, und der Benutzer kann von jedem Server Ihres Clusters lesen.

Trotz der scheinbaren Einfachheit gibt es mehrere Klassifizierungsmöglichkeiten fĂŒr verschiedene Implementierungen dieses Schemas:

  • Nach Rollen im Cluster (Master-Master oder Master-Slave)
  • Nach ĂŒbermittelten Objekten (zeilenbasiert, statements-basiert oder gemischt)
  • Nach dem Mechanismus zur Synchronisation der Knoten

Heute werden wir uns genau mit dem 3. Punkt beschÀftigen.

Wie der Commit einer Transaktion ablÀuft

Dieses Thema gehört nicht direkt zur Replikation, darĂŒber könnte ein separater Artikel geschrieben werden, aber da das VerstĂ€ndnis des Commit-Mechanismus fĂŒr das weitere Lesen unerlĂ€sslich ist, erlaube ich mir, die grundlegendsten Dinge in Erinnerung zu rufen. Der Commit einer Transaktion erfolgt in 3 Phasen:

  1. Aufzeichnung der Transaktion im Datenbankprotokoll.
  2. Anwendung der Transaktion im Datenbank-Engine.
  3. RĂŒcksendung der BestĂ€tigung an den Kunden ĂŒber die erfolgreiche Anwendung der Transaktion.

In verschiedenen Datenbanken können in diesem Algorithmus Nuancen auftreten: Zum Beispiel gibt es im InnoDB-Engine von MySQL 2 Protokolle: eines fĂŒr die Replikation (binary log) und ein anderes zur Aufrechterhaltung von ACID (undo/redolog), wĂ€hrend PostgreSQL ein Protokoll hat, das beide Funktionen erfĂŒllt (write ahead log = WAL). Aber oben wurde genau das allgemeine Konzept vorgestellt, das solche Nuancen unberĂŒcksichtigt lĂ€sst.

Synchronisierte (sync) Replikation

Lassen Sie uns dem Commit-Algorithmus der Transaktion Logik zur Replikation der erhaltenen Änderungen hinzufĂŒgen:

  1. Aufzeichnung der Transaktion im Datenbankprotokoll.
  2. Anwendung der Transaktion im Datenbank-Engine.
  3. Daten an alle Replikate senden.
  4. BestĂ€tigung von allen Replikaten ĂŒber die DurchfĂŒhrung der Transaktion erhalten.
  5. RĂŒcksendung der BestĂ€tigung an den Kunden ĂŒber die erfolgreiche Anwendung der Transaktion.

Bei diesem Ansatz ergeben sich einige Nachteile:

  • der Client wartet, bis die Änderungen auf allen Replikaten angewendet werden.
  • Mit zunehmender Anzahl der Nodes im Cluster verringern wir die Wahrscheinlichkeit, dass die Schreiboperation erfolgreich abgeschlossen wird.

Wenn der erste Punkt mehr oder weniger klar ist, sollte der zweite Punkt erlĂ€utert werden. Wenn bei synchroner Replikation keine Antwort von mindestens einem Node vorliegt, rollen wir die Transaktion zurĂŒck. So erhöht man, indem man die Anzahl der Nodes im Cluster vergrĂ¶ĂŸert, die Wahrscheinlichkeit, dass die Schreiboperation fehlschlĂ€gt.

Können wir nur auf eine bestimmte Anzahl von Nodes, zum Beispiel 51% (Quorum), eine BestÀtigung erwarten? Ja, das können wir, jedoch erfordert es im klassischen Szenario die BestÀtigung von allen Nodes, da wir nur so die vollstÀndige Konsistenz der Daten im Cluster gewÀhrleisten können, was unbestreitbar ein Vorteil dieser Replikationsart ist.

Asynchrone (async) Replikation

Lassen Sie uns den vorherigen Algorithmus abwandeln. Wir werden die Daten an die Replikate "irgendwann spĂ€ter" senden, und "irgendwann spĂ€ter" werden die Änderungen auf den Replikaten angewendet:

  1. Aufzeichnung der Transaktion im Datenbankprotokoll.
  2. Anwendung der Transaktion im Datenbank-Engine.
  3. RĂŒcksendung der BestĂ€tigung an den Kunden ĂŒber die erfolgreiche Anwendung der Transaktion.
  4. Daten an die Replikate senden und Änderungen anwenden.

Dieser Ansatz fĂŒhrt dazu, dass der Cluster schnell arbeitet, da wir den Client nicht warten lassen, bis die Daten zu den Replikaten gelangen und auch noch festgeschrieben werden.

Aber die Bedingung, Daten "irgendwann spĂ€ter" auf die Replikate zu ĂŒbertragen, kann dazu fĂŒhren, dass Transaktionen verloren gehen, insbesondere bestĂ€tigte Transaktionen fĂŒr den Benutzer, denn wenn die Daten nicht rechtzeitig repliziert wurden, wird die BestĂ€tigung an den Client ĂŒber den erfolgreichen Abschluss der Operation gesendet, und wenn das HDD des Nodes, an den die Änderungen gesendet wurden, ausfĂ€llt, verlieren wir die Transaktion, was zu sehr unangenehmen Folgen fĂŒhren kann.

Halbsynchrone (semisync) Replikation

Endlich haben wir die semi-synchrone Replikation erreicht. Diese Art der Replikation ist nicht sehr bekannt und nicht weit verbreitet, bietet jedoch ein gewisses Interesse, da sie die Vorteile sowohl der synchronen als auch der asynchronen Replikation kombinieren kann.

Lass uns die beiden vorherigen AnsÀtze kombinieren. Wir werden den Client nicht lange warten lassen, verlangen jedoch, dass die Daten repliziert werden:

  1. Aufzeichnung der Transaktion im Datenbankprotokoll.
  2. Anwendung der Transaktion im Datenbank-Engine.
  3. Daten an die Replikate senden.
  4. Erhalt einer BestĂ€tigung von der Replik ĂŒber den Erhalt der Änderungen (diese werden "irgendwann spĂ€ter" angewendet).
  5. RĂŒcksendung der BestĂ€tigung an den Kunden ĂŒber die erfolgreiche Anwendung der Transaktion.

Beachte, dass bei diesem Algorithmus der Verlust einer Transaktion nur dann auftritt, wenn sowohl der Knoten, der die Änderungen akzeptiert, als auch der Replikationsknoten ausfallen. Die Wahrscheinlichkeit eines solchen Ausfalls wird als gering eingeschĂ€tzt, und diese Risiken werden akzeptiert.

Bei diesem Ansatz besteht jedoch das Risiko von Phantomlesen. Stellen wir uns folgendes Szenario vor: In Schritt 4 haben wir von keiner Replik eine BestĂ€tigung erhalten. Wir mĂŒssen diese Transaktion zurĂŒcksetzen, ohne dem Client eine BestĂ€tigung zurĂŒckzugeben. Da die Daten in Schritt 2 angewendet wurden, entsteht zwischen dem Ende von Schritt 2 und dem ZurĂŒcksetzen der Transaktion ein Zeitfenster, in dem parallele Transaktionen die Änderungen sehen könnten, die in der Datenbank nicht vorhanden sein sollten.

Lose-less semi-synchrone Replikation

Wenn man ein wenig nachdenkt, kann man durch einfaches Vertauschen der Schritte im Algorithmus das Problem der Phantomlesungen in diesem Szenario beheben:

  1. Aufzeichnung der Transaktion im Datenbankprotokoll.
  2. Daten an die Replik senden.
  3. Erhalt einer BestĂ€tigung von der Replik ĂŒber den Erhalt der Änderungen (diese werden "irgendwann spĂ€ter" angewendet).
  4. Anwendung der Transaktion im Datenbank-Engine.
  5. RĂŒcksendung der BestĂ€tigung an den Kunden ĂŒber die erfolgreiche Anwendung der Transaktion.

Jetzt bestĂ€tigen wir die Änderungen nur, wenn sie repliziert wurden.

Ausgabe

Wie immer gibt es keine perfekten Lösungen, sondern eine Reihe von Lösungen, von denen jede ihre eigenen Vor- und Nachteile hat und fĂŒr die Lösung verschiedener Klassen von Aufgaben geeignet ist. Dies gilt auch fĂŒr die Wahl des Mechanismus zur Synchronisierung der Daten der replizierten Datenbank. Das Set an Vorteilen, das die semi-synchrone Replikation bietet, ist ziemlich solide und interessant genug, um als bemerkenswert eingestuft zu werden, trotz ihrer geringen Verbreitung.

Das wÀre alles. Bis zum nÀchsten Mal bei Kurs!

Quelle: habr.com

ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server đŸ”„ ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster