Zum Hauptinhalt springen

21 Posts getaggt mit "Architektur"

Muster für Systemarchitektur und Infrastrukturdesign.

Alle Tags anzeigen

Ein Owner, der neu startet, hat kein Recht auf seine eigene Leere

· 13 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Einen neu gestarteten Owner aus seinen Replicas wiederaufbauen

Ein Failover deckt den Moment ab, in dem ein Owner stirbt: Der Cluster wählt einen Überlebenden und bedient weiter. Eine geplante Migration deckt das absichtliche Verschieben der Partition eines gesunden Owners ab. Dieser Beitrag handelt vom dritten Akt, dem, der nach dem Ende der Sirenen abläuft — der ursprüngliche Owner-Prozess startet neu, tritt dem Cluster wieder bei und will seine Partition zurück. Sein Store, der nichts auf der Platte und alles im Speicher hält, kam leer zurück. Die Daten, für die er verantwortlich ist, leben noch, aber auf den Replicas, die weiter bedient haben, während er ausgefallen war.

Das gesamte Korrektheitsproblem steckt in einem Satz: Dem neu gestarteten Owner darf nicht erlaubt werden, seiner eigenen Leere zu trauen. Ein leerer Store sieht genau so aus wie ein Store, den jemand bewusst geleert hat. Nimmt der Node an „ich bin der Owner und habe keine Daten, also ist diese Partition leer", wird er bereitwillig NotFound für Millionen lebender Keys ausliefern und, schlimmer, seinen leeren Zustand zurück auf die Replicas fließen lassen und sie löschen. Dieser Beitrag geht die fünf kleinen, reinen Policies durch, mit denen Zaris sicherstellt, dass das nie geschieht.

Wie ein Zaris-Cluster hochfährt: Mitgliedschaft, die Map und durch Konvergenz gesteuerte Readiness

· 14 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Wie ein Zaris-Cluster hochfährt: Mitgliedschaft, die Map und durch Konvergenz gesteuerte Readiness

Die meisten Texte über verteilte Stores handeln vom Normalbetrieb — Lesen, Schreiben, Replikation — oder von den dramatischen Ausfällen: einem Failover, wenn ein Owner stirbt, oder einem Cut-over, wenn eine Partition umzieht. Doch es gibt einen leiseren Moment, der darüber entscheidet, ob all das funktioniert: der Moment, in dem der Cluster hochfährt. Bevor auch nur ein Key geroutet werden kann, müssen sich die Nodes einigen, wer zum Cluster gehört, wem welcher Ausschnitt des Keyspace gehört und — der Schritt, den die meisten Systeme falsch machen — ob es überhaupt sicher ist, mit dem Bedienen zu beginnen.

Dieser Beitrag folgt dieser Boot-Sequenz in der Reihenfolge, in der Zaris sie tatsächlich ausführt: Mitgliedschaft, Partition-Map und die Readiness-Gates, die zwischen „der Prozess läuft" und „der Node nimmt Traffic an" stehen. Außerdem ziehen wir ehrlich eine Grenze zwischen dem, was Zaris selbst implementiert, und dem, was es von der zugrunde liegenden Cluster-Laufzeit erbt, auf der es aufbaut.

Zwei Cluster, ein Change Feed: Replikation über ein WAN, ohne Zaris zu strecken

· 10 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Zwei unabhängige Cluster, verbunden durch einen wiederaufnehmbaren Change Feed über ein WAN

Früher oder später stellt jemand die Frage: Wir haben einen Cluster in einer Region und Nutzer in einer anderen — können wir nicht einfach dort ein paar Nodes hinzufügen und einen Cluster beide Regionen umspannen lassen? Das ist ein nachvollziehbarer Instinkt. Ein Cluster, ein Namespace, ein Connection-String, Daten überall. Der Instinkt ist aber auch eine Falle, und es lohnt sich, genau zu erklären, warum.

Ein Zaris-Cluster ist für ein Datacenter-Netzwerk konstruiert. Die Mitgliedschaft wird mit Heartbeats auf kurzen Timern verfolgt. Das Ownership einer Partition wechselt zwischen Nodes über einen Handshake, der voraussetzt, dass die Gegenseite schnell antwortet. Das Failover fenced einen vermutlich toten Owner und befördert eine Replica im Sekundenbereich. Jeder dieser Mechanismen ist für eine Verbindung kalibriert, bei der die Round-Trip-Zeit in Mikrosekunden gemessen wird und ein „langsamer" Node tatsächlich krank ist — nicht bloß achtzig Millisekunden und einen Ozean entfernt. Setzt man die Hälfte der Nodes über ein WAN, hat man keinen georedundanten Cluster gebaut, sondern einen Cluster, der normale WAN-Latenz nun für einen Ausfall hält, das Ownership flattern lässt und beim ersten Aussetzer der Verbindung zwischen den Regionen ein Split-Brain riskiert.

Die richtige Form ist also nicht ein gestreckter Cluster. Es sind zwei unabhängige Cluster — jeder in sich geschlossen, mit eigenem Ownership und Failover, das vollständig im eigenen LAN bleibt —, verbunden durch einen asynchronen, wiederaufnehmbaren Change Feed. Dieser Beitrag handelt von diesem Muster: warum Unabhängigkeit die tragende Entscheidung ist und wie das Operation-Log von Zaris Ihnen bereits das Eine liefert, was ein WAN-Replikator tatsächlich braucht — einen Cursor, von dem aus Sie fortsetzen können.

Der Latenzboden: Eine Mikrosekunde Arbeit in zehn Mikrosekunden Installation

· 11 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Eine Mikrosekunde Arbeit in zehn Mikrosekunden Installation

Hier ist eine Zahl, die verändert, wie man über einen Key/Value-Store denkt. Wenn wir den In-Memory-Store von Zaris isolieren und ihm Operationen zuführen, ohne dass etwas anderes im Weg ist — kein Socket, keine Serialisierung, kein Routing —, bedient ein einzelner Thread mehr als eine Million Lesezugriffe pro Sekunde und skaliert sauber auf mehr als acht Millionen über acht Threads. Der Store erledigt die eigentliche Arbeit eines GET also in unter zwei Mikrosekunden und ist ausdrücklich nicht der Engpass.

Und doch erreicht ein vollständiges GET über eine echte TCP-Verbindung auf derselben Maschine ein Plateau bei einigen Hunderttausend pro Sekunde. Der Store kann die Arbeit fünfmal schneller erledigen, als der Server sie liefern kann. Die interessante Performance-Frage zu Zaris lautet also nicht „Wie schnell ist der Store?" Sondern genau umgekehrt: Wohin geht die ganze Zeit zwischen Socket und Store? Dieser Beitrag ist die Antwort, Operation für Operation nachverfolgt, denn die Lücke zwischen 1,7 Mikrosekunden Logik und 10 bis 13 Mikrosekunden Server-CPU pro Operation ist kein Rauschen — sie ist der Latenzboden, und fast alles davon ist Installation.

Eine Partition ohne Datenverlust migrieren: das Cut-over-Protokoll

· 13 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Das Zaris-Partition-Cut-over-Protokoll

Ein Failover ist das, was passiert, wenn ein Owner stirbt — der Cluster hat Sekunden, um einen Überlebenden zu wählen, und die Partition-Map bewegt sich nie. Migration ist der ruhigere, gefährlichere Cousin: Der Owner ist völlig gesund, und Sie wollen eine Partition absichtlich von ihm wegbewegen — um den Cluster zu vergrößern, neu zu balancieren oder einen Node zu leeren, den Sie außer Dienst stellen wollen. Nichts ist ausgefallen, und genau deshalb liegt die Latte höher. Ein Failover darf im schlimmsten Fall einige ehrlich verlorene Schreibzugriffe am Ende in Kauf nehmen; eine geplante Migration nicht. Wenn das Verschieben einer Partition von Node A zu Node B einen einzigen bestätigten Schreibzugriff verlieren kann, ist Migration kein Feature, sondern eine Belastung.

Dieser Beitrag geht das Cut-over-Protokoll durch, das Zaris tatsächlich ausführt, in dieser Reihenfolge, und verbringt die meiste Zeit bei dem einen Schritt, den alle falsch machen: dem Moment, in dem die Quelle schließlich „frei" ist, ihre Kopie zu verwerfen. Dieser Schritt ist eine geladene Waffe, und das Interessante an der Ingenieursarbeit ist die Sicherung daran.

Einen Keyspace scannen, der nicht stillhält: Wie SCAN einen Cluster durchläuft

· 10 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Viele sortierte Segmente, zusammengeführt zu einem geordneten, seitenweisen Strom

Ein einzelnes GET auf einen Key ist leicht zu durchdenken: den Key hashen, den Owner finden, genau diesen einen Node fragen. SCAN ist die gegenteilige Art von Operation. Es hat keinen Key — es stellt eine Frage über den gesamten Keyspace: Gib mir jeden Key in diesem Bereich, Seite für Seite. Und in einem partitionierten, replizierten Store ist dieser Keyspace nicht eine Sache an einem Ort. Er ist über 256 Segmente verteilt, die auf so viele Nodes entfallen, wie Sie betreiben, wobei jeder Node nur die Ausschnitte hält, die er gerade besitzt, und während Sie iterieren, wird in die Gesamtheit geschrieben. Es gibt keinen globalen sortierten Index zum Durchlaufen. Woher kommt also die Ordnung, worauf zeigt ein Resume-Token genau, und was passiert mit Ihrem Scan, wenn mittendrin ein Key geschrieben wird — oder eine Partition umzieht?

Dieser Beitrag folgt einem SCAN durch die drei Schichten, die ihn tatsächlich bedienen: ein einzelnes Segment, ein einzelner Node und der Client, der die Nodes zusammenfügt. Jede Schicht löst ein Teilstück des Problems, und die ehrlichen Grenzen der Operation ergeben sich daraus, wie diese Teile zusammenpassen.

Die Speicherobergrenze: Warum ein Zaris-Node nie unbegrenzt wächst

· 10 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Ein Zaris-Node hält die Speichernutzung in einem ruhigen Band unterhalb seiner Obergrenze und führt bei 80 % eine Eviction bis hinunter auf 70 % durch, sodass Schreibzugriffe das Limit nie überschreiten

Hier ist eine Frage, die einfach klingt und es nicht ist: Was passiert, wenn einem In-Memory-Store der Speicher ausgeht?

Die naive Antwort lautet „er stürzt ab" — der Prozess wächst, bis das Betriebssystem ihn beendet. Die etwas weniger naive Antwort lautet „er lehnt Schreibzugriffe ab". Zaris tut standardmäßig keines von beidem. Ein Zaris-Node ist ein In-Memory-Store, aber bewusst kein unbegrenzter: Jeder Node ist ein begrenzter Puffer mit einer harten Obergrenze, und wenn sich die Daten, die er besitzt, dieser Obergrenze nähern, entfernt der Node seine kältesten Daten, um Platz zu schaffen. Schreibzugriffe gelingen weiter; das Limit hält; der Prozess bläht sich nicht auf. Der Node verhält sich wie ein Cache, denn darunter ist er einer.

Was über die Leitung geht: Die Anatomie eines Zaris-Records

· 12 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Die Anatomie eines gespeicherten Zaris-Records

Das meiste von dem, was Zaris gut macht — einen Schreibzugriff auf ein Backup replizieren, eine hinterherhinkende Replica aufholen lassen, eine Partition auf einen neuen Owner umschalten —, läuft auf eine stille Frage hinaus: Was genau ist die Dateneinheit, die zwischen Nodes wandert? Stimmt diese Einheit, ist Konvergenz fast langweilig. Lässt sie ein Feld weg oder trägt das falsche, bekommen Sie einen wiederauferstandenen gelöschten Key, eine Replica, die Veraltetes nicht von Frischem unterscheiden kann, oder die Buchführung eines Nodes sickert auf einen anderen.

In Zaris ist diese Einheit ein einziger Typ — StoredRecord — und es lohnt sich, ihn Feld für Feld auseinanderzunehmen, denn jede Entscheidung darin ist tragend. Dieser Beitrag ist die Anatomie: was im Record steckt, wie er auf der Leitung gerahmt wird, warum ein Löschvorgang als Record statt als Abwesenheit reist, warum es zwei verschiedene Versionsnummern gibt und — genauso wichtig — was bewusst auf jedem Node zurückbleibt und die Leitung nie überquert.

Drop-in-Cache für ASP.NET Core: IDistributedCache und HybridCache auf Zaris

· 10 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Drop-in-verteilter-Cache für ASP.NET Core auf Zaris

Die meisten Gründe, in einer .NET-App zu einem verteilten Cache zu greifen, nennen den Cache gar nicht beim Namen. Sie aktivieren Output Caching, und es verlangt ein IDistributedCache. Sie aktivieren Sessions, und die Middleware will einen Backing-Store. Sie schalten das Teilen von Data-Protection-Schlüsseln über Instanzen hinweg ein, und wieder braucht es einen Ort für Bytes, den jeder Node sieht. Der Anwendungscode ist gegen eine Abstraktion geschrieben; offen ist nur, welche Implementierung Sie beim Start registrieren.

Zaris beantwortet diese Frage mit drei kleinen NuGet-Paketen, die jeweils eine bestimmte ASP.NET-Core-Nahtstelle bedienen: ein schlichtes IDistributedCache, ein zweistufiges HybridCache und ein Session-Store. Sie registrieren beim Start eine Zeile, und der Rest Ihrer App — einschließlich Drittanbieter-Bibliotheken, die nur die Abstraktion kennen — cacht auf einem Zaris-Cluster, ohne dass sich der Code ändert, der den Cache nutzt. Dieser Beitrag geht alle drei durch und ist dabei bewusst klar darüber, wo jedes ehrlicherweise endet.

Anatomie eines Failovers: Was mit einem laufenden Schreibvorgang geschieht, wenn der Owner stirbt

· 12 Minuten Lesezeit
Clustron Team
Engineering für verteilte Systeme

Anatomie eines Failovers in Zaris

Ein Failover ist der Moment, in dem ein verteilter Store am ehrlichsten zeigt, was er wirklich ist. Im Normalbetrieb sehen alle Stores gleich aus: Ein Schreibvorgang landet auf einem Owner, wird bestätigt, weiter geht's. Das Design zeigt sich erst, wenn der Owner mitten im Satz verschwindet — ein Node hält die aktive Kopie einer Ihrer Partitionen, Schreibvorgänge landen gerade auf ihm, und dann ist er weg. Hart beendet. Netzwerkpartitioniert. OOM. Der Cluster hat ein paar Sekunden, um das zu bemerken, sich auf einen neuen Owner zu einigen und den Verkehr wieder fließen zu lassen — und ob er das korrekt tut, entscheidet darüber, ob Ihr bestätigter Schreibvorgang überlebt oder stillschweigend verdunstet.

Dieser Beitrag folgt dieser Abfolge von Anfang bis Ende, in der Reihenfolge, in der Zaris sie tatsächlich ausführt, und benennt die Fälle, in denen die Antwort wirklich „der Schreibvorgang ist verloren" lautet — denn ein Failover-Beitrag, der nur den Happy Path beschreibt, ist nicht lesenswert.