Zum Hauptinhalt springen

Konsistenzmodell

Clustron Zaris bietet Ihnen eine konsistente und vorhersagbare Sicht auf Ihre Daten über Nodes hinweg. Dieser Artikel erklärt, was das in der Praxis bedeutet, damit Sie das Verhalten von Lese- und Schreibzugriffen vorhersagen können — und wissen, wann Sie zusätzlich Koordination benötigen.

Was Konsistenz hier bedeutet​

Konsistenz beschreibt, wie sich Daten verhalten, wenn mehr als eine Sache gleichzeitig passiert: Mehrere Nodes halten die Daten, mehrere Clients lesen und schreiben denselben Schlüssel, und Updates treffen nebenläufig ein. Das Modell soll drei Ziele ausbalancieren — Korrektheit, Verfügbarkeit und Performance —, damit es nicht absolute Garantien auf Kosten der Nutzbarkeit verfolgt.

Ein logischer Store​

Auch im verteilten Modus präsentiert sich ein Store als ein einziger logischer Store. Sie sprechen den Store an, nicht einzelne Nodes, und Sie verwalten weder die Replikation noch leiten Sie Anfragen selbst an bestimmte Nodes. Viele Nodes tragen den Store, aber Sie denken in einer konsistenten Sicht:

Mehrere Nodes → eine konsistente Sicht

Das ist das Fundament, auf dem alles Weitere ruht: Ihr Anwendungscode behandelt einen verteilten Store genauso wie einen In-Process-Store.

Wie sich Lese- und Schreibzugriffe verhalten​

Schreibvorgänge werden über den Cluster angewendet, der den Store beim Eintreffen von Änderungen in einem konsistenten Zustand hält. Sie koordinieren die Replikation zwischen Nodes nicht — das ist Aufgabe des Systems.

Lesezugriffe liefern den neuesten bekannten Wert. Entscheidend: Sobald ein Schreibvorgang erfolgreich war, spiegeln nachfolgende Lesezugriffe ihn wider. Dieses Read-after-write-Verhalten ermöglicht es, einen Wert zu schreiben und sich darauf zu verlassen, ihn wieder lesen zu können, statt zu zweifeln, ob sich das Update bereits verbreitet hat.

hinweis

Read-after-write gilt, weil Lesezugriffe standardmäßig an den Primary gehen und dort die Schreibvorgänge landen. Wenn Sie Replica-Reads (AllowReplicaReads) bei der standardmäßigen Async-Replikation aktivieren, kann ein von einem hinterherhinkenden Replica bedienter Lesezugriff veraltete Daten liefern — Read-after-write ist dann nicht mehr garantiert. Details zu Routing und Replikationsmodi finden Sie unter Partitionierung und Replikation.

Für die meisten Anwendungen bedeutet das: Sie interagieren mit dem Store wie mit einer einzelnen Instanz — vorhersagbare Lese- und Schreibzugriffe, keine manuelle Replikation und keine Konsistenzbuchführung über Nodes hinweg.

Konsistenz konfigurieren​

Die Stellschrauben, die diese Garantien formen, liegen in der Store-Konfiguration. Die Defaults (Async-Replikation, Reads nur vom Primary) liefern Read-after-write sofort einsatzbereit; ändern Sie sie, wenn ein Workload andere Abwägungen braucht:

  • Replikationsmodus — replication.mode: Async (Default; niedrigste Latenz, ein Failover kann die jüngsten Schreibvorgänge verlieren) oder Sync (wartet auf Replicas, stärkere Dauerhaftigkeit). Bei Sync entscheidet replication.quorum (All, Majority oder BestEffort), wie viele Replicas bestätigen müssen.
  • Replica-Reads — reads.allowReplicaReads (Default false). Aktivieren Sie dies nur für leselastige Workloads, die leicht veraltete Lesezugriffe tolerieren; es tauscht Read-after-write gegen Lesedurchsatz.
{
"replication": { "factor": 2, "mode": "Sync", "quorum": "Majority" },
"reads": { "allowReplicaReads": false }
}

Der Replikations-Faktor wird beim Erstellen des Stores festgelegt (New-ZrStore -ReplicationFactor). Alle Felder und Defaults finden Sie in der Konfigurationsreferenz.

Nebenläufige Updates desselben Schlüssels​

Wenn mehrere Clients denselben Schlüssel gleichzeitig aktualisieren, verarbeitet der Store die Operationen sicher und einigt sich auf ein konsistentes Ergebnis — Sie erhalten keinen beschädigten oder halb geschriebenen Wert. Was ein einfacher Schreibvorgang nicht tut, ist zu prüfen, ob jemand anderes den Schlüssel zuvor geändert hat.

warnung

Ein einfaches PutAsync ist ein Blind Write: Es überschreibt, was auch immer vorhanden ist, sodass zwei Clients, die denselben Schlüssel nebenläufig aktualisieren, ein Lost Update erzeugen können — der zweite Schreibvorgang ersetzt den ersten stillschweigend. Hängt die Korrektheit eines Updates vom gelesenen Wert ab, verlassen Sie sich nicht auf gewöhnliche Schreibvorgänge. Verwenden Sie eine Transaktion, die eine konkurrierende Änderung erkennt und fehlschlägt, statt zu überschreiben, oder einen Lock bzw. Lease, damit nur ein Client den Schlüssel zur Zeit aktualisiert.

Dasselbe Modell in beiden Modi​

Das Konsistenzmodell ist im In-Process- und im verteilten Modus identisch. Ihre Anwendung braucht keine unterschiedliche Logik je nachdem, wo der Store läuft; deshalb ist es sicher, gegen einen In-Process-Store zu entwickeln und gegen einen verteilten bereitzustellen.

Wenn Sie stärkere Garantien brauchen​

Das Standardverhalten genügt für einfache Lese- und Schreibzugriffe. Braucht eine Operation Reihenfolge, Exklusivität oder Alles-oder-nichts-Semantik, greifen Sie zu den Koordinationsprimitiven:

  • Locks, um einem Client exklusiven Zugriff zu geben und konkurrierende Updates zu verhindern.
  • Transaktionen, um mehrere Operationen zu gruppieren, sodass sie gemeinsam angewendet werden, mit Konflikterkennung durch optimistische Nebenläufigkeit.
  • Leases, um den Besitz einer Ressource zu verwalten und sie bei einem Ausfall automatisch freizugeben.

So führen Sie stärkere Koordination genau dort ein, wo Sie sie brauchen, ohne bei jeder Operation dafür zu zahlen.

Nächste Schritte​