Zum Hauptinhalt springen

6 Posts getaggt mit "Verteilte Muster"

Gängige Muster in verteilten Systemen.

Alle Tags anzeigen

Welches Primitiv für welches Problem: Ein Feldführer durch das Zaris-Datenmodell

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

Das richtige Zaris-Primitiv für das Problem wählen

Der Großteil dieses Blogs ist jeweils tief in ein einzelnes Thema eingestiegen — Compare-and-Swap, Multi-Key-Transaktionen, native Datenstrukturen, Streams, Watch, das darunterliegende Op-Log. Jeder Beitrag beantwortet „wie funktioniert dies". Dieser beantwortet eine andere, praktischere Frage: Wonach greifen Sie, wenn ein Problem vor Ihnen liegt?

Diese Frage ist wichtig, weil die falsche Wahl selten ein Absturz ist. Es ist ein System, das in der Demo funktioniert und dann unter Last ein Update verliert, tausend Schreiber durch einen Schlüssel schleust oder eine Fire-and-Forget-Benachrichtigung nutzt, wo ein dauerhaftes Log nötig war. Die Primitive hindern Sie nicht daran, sie falsch zu benutzen. Dies ist also ein Feldführer: das mentale Modell, das sie verbindet, eine Entscheidungstabelle, ein Gang durch jeden Zweig mit ehrlicher Eignung und ehrlicher Grenze und am Ende ein Flussdiagramm.

Keyspace-Benachrichtigungen, die ein Failover überstehen

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

Redis-Keyspace-Benachrichtigungen auf dem replizierten nativen Watch von Zaris

Keyspace-Benachrichtigungen sind eines der nützlichsten Features von Redis und eines der unauffällig fragilsten. Die Idee ist wunderbar: Jedes Mal, wenn ein Schlüssel geschrieben, gelöscht oder ablaufend ist, veröffentlicht der Server ein Event auf einem wohlbekannten Pub/Sub-Kanal, und jeder Interessierte kann per PSUBSCRIBE reagieren — einen Cache invalidieren, einen Worker wecken, eine Projektion aktualisieren. Kein Polling, kein GET in einer Schleife, das fragt „hat es sich schon geändert?".

Die Fragilität steckt im Kleingedruckten. Redis-Keyspace-Benachrichtigungen sind Fire-and-Forget-Pub/Sub, ausgesendet von dem Node, der den Befehl verarbeitet hat, an Subscriber, die mit genau diesem Node verbunden sind. In einem geclusterten Deployment heißt das: Ein Subscriber hört nur von Schreibvorgängen, die zufällig auf dem Node landeten, an den er angebunden ist, und fällt dieser Node per Failover aus, geht die Subscription — und der Event-Strom, den sie trug — mit. Das Feature funktioniert auf einer einzelnen Box wunderbar und wird schnell subtil, sobald es mehr als eine gibt.

Zaris spricht exakt dasselbe Protokoll — CONFIG SET notify-keyspace-events, die Kanäle __keyspace@0__ und __keyevent@0__, ein gewöhnliches PSUBSCRIBE von jedem Redis-Client in jeder Sprache. Die Mechanik darunter ist jedoch keine Neuimplementierung des Redis-Notifiers. Es ist eine dünne Brücke auf ein Feature, das Zaris bereits hatte: einen nativen, clusterweiten, replizierten Watch. Das ändert, was die Benachrichtigungen wert sind.

Alles oder nichts: Multi-Key-Transaktionen in Zaris

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

Multi-Key-Transaktionen in Zaris

Ein Begleitbeitrag, Race-Free Coordination on Optimistic CAS, hat dargelegt, dass ein einziges Primitiv — eine vom Store vergebene Version plus ein versionsgeschütztes bedingtes Schreiben — erstaunlich viel Koordination trägt. Er zog auch eine harte Grenze: CAS ist atomar auf einem Key. Bewegen Sie Geld von Konto A auf Konto B, kann ein einzelnes Compare-and-Swap nicht beides abdecken; der ehrliche Rat lautete, die Überweisung als Zustandsmaschine auf einem Key zu modellieren oder zu einer Saga zu greifen.

Diese Grenze ist real, aber sie ist nicht die ganze Geschichte. Zaris hat eine echte Multi-Key-Transaktion — BeginTransactionAsync, ein gestaffeltes Lese-/Schreib-Set, CommitAsync — und sie committet über Keys und über Nodes hinweg mit einer Alles-oder-nichts-Garantie. Dieser Beitrag handelt davon, was diese Transaktion unter der Haube tatsächlich ist (ein clientkoordinierter Two-Phase-Commit über optimistische Versionen), was sie genau garantiert und welche Feinheit darüber entscheidet, ob Ihre Key-übergreifende Invariante tatsächlich hält.

Ein Primitiv, viele Garantien: Race-freie Koordination mit optimistischem CAS

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

Race-freie Koordination mit dem optimistischen CAS von Zaris

Es ist verlockend, einen Datenspeicher an der Länge seiner Befehlsliste zu messen. Redis hat INCR, SETNX, MULTI/EXEC, WATCH, Lua, SCAN, Pub/Sub — für jeden Anlass ein eigenes Verb. Der Zaris-.NET-Client wirkt dagegen fast asketisch. Es gibt kein serverseitiges atomares Increment. Es gibt keine allgemeine Multi-Key-Transaktion, die beliebige Logik ausführt. Es gibt keinen Prefix-Scan. Natives Pub/Sub existiert nur über das RESP-Frontend, nicht im typisierten .NET-Client.

Stattdessen bietet Ihnen der .NET-Client ein kleines, scharfes Koordinationsprimitiv: optimistisches, versioniertes Compare-and-Swap. Dieser Beitrag zeigt, wie weit dieses eine Primitiv tatsächlich trägt — denn die ehrliche Antwort lautet: überraschend weit. Ein Rate Limiter, ein Wallet, das unter tausend gleichzeitigen Abbuchungen nie ins Minus rutscht, eine Job-Queue, in der genau ein Worker jeden Job übernimmt, und ein Feature-Flag-Regelwerk, das bei gleichzeitigen Admin-Änderungen nie ein Update verliert. Alles aus demselben Primitiv, ohne zusätzliche serverseitige Mechanik.

Retries, die Sie nicht schreiben müssen: Ownership-Churn im Zaris-Client überstehen

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

Transparenter Retry und Reroute bei Ownership-Churn

Hier eine Tatsache über jeden partitionierten Key/Value-Store, die die glänzenden Diagramme gern auslassen: Der Node, der Ihren Schlüssel besitzt, wird wechseln. Ein Node fällt aus, und seine Partitionen gehen per Failover auf ihre Replikate über. Sie skalieren aus, und Partitionen wandern auf das neue Mitglied. Ein bevorzugter Primary kehrt zurück, und der Besitz fällt an ihn zurück. Jedes dieser Ereignisse bedeutet: Der Node, mit dem Ihr Client vor einer Millisekunde noch zufrieden sprach, ist jetzt für einen Teil der Schlüssel der falsche.

Die naive Client-Erfahrung in diesem Moment ist hässlich: ein Verbindungsabbruch, ein generischer „Serverfehler" oder — schlimmer — ein Schreibvorgang, der auf einem Node landet, der nicht mehr der aktive Owner ist, und stillschweigend im Nichts verschwindet. Der Zaris-.NET-Client ist so gebaut, dass nichts davon Ihren Code erreicht. Ein Ownership-Wechsel wird zu einem typisierten Status, der Client routet um zum neuen Owner, und der Retry ist sowohl durch ein Versuchsbudget als auch durch eine Wanduhr-Deadline begrenzt. Im Normalfall dauert Ihr PutAsync einfach ein paar Millisekunden länger und liefert Ok. Dieser Beitrag beschreibt die Mechanik dahinter — und ebenso wichtig: die Fälle, die sie bewusst nicht überdeckt.

Von Redis kommend: Ihre .NET-App auf Zaris umstellen

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

Zwei Wege von Redis zu Zaris

Wenn Ihre .NET-Dienste bereits mit Redis kommunizieren, muss der Wechsel zu Zaris kein Rewrite sein. Zaris ist ein verteilter, replizierter In-Memory-Key/Value-Store, der nativ für .NET gebaut wurde — und seit 2.0.0 spricht er zwei Protokolle gleichzeitig: sein eigenes effizientes binäres Protokoll für erstklassige .NET-Clients und ein Redis-kompatibles RESP2-Frontend, auf das jeder Redis-Client in jeder Sprache zeigen kann.

Daraus ergeben sich zwei ehrliche Migrationspfade, die sich nicht gegenseitig ausschließen. Sie können mit dem RESP-Pfad ohne Änderungen beginnen, um Zaris heute unter Last zu bringen, und den nativen Client dort einführen, wo es sich lohnt. Dieser Beitrag geht beide Pfade durch und gibt Ihnen eine klare Regel für die Wahl an die Hand.