Zum Hauptinhalt springen

8 Posts getaggt mit "Redis"

Redis-Kompatibilität, Migration und das RESP-Protokoll.

Alle Tags anzeigen

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.

Drei Wege zum Failover: LoadBalancer, Sentinel und Cluster im Zaris-RESP-Frontend

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

Drei Wege zum Failover im Zaris-RESP-Frontend

Zaris stellt ein Redis-Protokoll-Frontend (RESP) bereit, sodass jeder Redis-Client in jeder Sprache auf einen Zaris-Cluster zeigen und ihn als Drop-in-Store nutzen kann. Doch „jeder Redis-Client" verbirgt ein reales Problem: Die Redis-Client-Ökosysteme sind sich nicht einig, wie die Topologie ermittelt wird oder wie man reagiert, wenn ein Node verschwindet. Ein einfacher Client erwartet einen einzelnen, stabilen Endpunkt. Ein Sentinel-basierter Client erwartet, einen Discovery-Dienst fragen zu können: „Wer ist der Master?" Ein Client im Cluster-Modus erwartet Hash-Slots und MOVED/ASK-Redirects.

Würde ein Store nur einen dieser Dialekte sprechen, blieben ganze Client-Klassen außen vor. Deshalb unterstützt das Zaris-RESP-Frontend drei Failover-Modelle, die jeweils dazu passen, wie eine bestimmte Familie von Redis-Clients bereits arbeitet. Sie wählen das Modell pro Deployment; der Client verhält sich genau so, wie er es gegenüber echtem Redis tun würde.

Vorab ein ehrlicher Hinweis, der alles Folgende prägt: Alle drei Modelle sitzen vor demselben replizierten, partitionierten Zaris-Store. Das gewählte Modell ändert die Semantik von Discovery und Redirects — also wie ein Client einen Node findet und was er tut, wenn dieser ausfällt —, nicht aber, wo Ihre Daten tatsächlich liegen.

Redis Streams nativ: Append-only-Logs, Consumer Groups und blockierende Lesezugriffe

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

Ein natives, repliziertes Append-only-Log mit Consumer Groups und blockierenden Lesezugriffen in Zaris

Zaris spricht bereits in Collections — Hashes, Listen, Sets und Sorted Sets, die auf dem Server liegen und wie jeder andere Key repliziert werden. Streams sind die fünfte Art, und sie ist diejenige, die aus Zaris vom Store ein Stück Messaging-Infrastruktur macht.

Ein Zaris-Stream ist ein echtes Append-only-Log: Einträge erhalten monoton steigende IDs, Sie können Bereiche lesen, und Sie können Consumer Groups anbinden, sodass ein Pool von Workern das Log untereinander aufteilt, pro Consumer ausstehende Einträge verfolgt und bestätigt, was verarbeitet wurde. Sie können außerdem einen blockierenden Lesezugriff ausführen — ein Consumer parkt und wartet, bis neue Einträge eintreffen, statt in einer Schleife zu hämmern.

Und weil es eine native Zaris-Collection ist, wird das Log genau wie alles andere partitioniert und repliziert. Ein Stream übersteht ein Node-Failover, und genau dafür greift man überhaupt erst zu dauerhaftem Messaging.

Datenstrukturen, die replizieren: Hashes, Listen, Sets und Sorted Sets in Zaris

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

Native Hashes, Listen, Sets und Sorted Sets, repliziert wie jeder andere Key in Zaris

Zaris 1.x speicherte Werte. Zaris 2.0.0 speichert Collections. Hashes, Listen, Sets und Sorted Sets sind nun erstklassige, serverseitige Typen mit echten, typisierten .NET-APIs — und, ebenso wichtig, sie verhalten sich wie alles andere im Store.

Genau diesen letzten Punkt machen viele falsch. In vielen Systemen sind „Datenstrukturen“ eine clientseitige Illusion: Eine Bibliothek serialisiert ein Dictionary in einen Blob, schreibt es per Put und nennt das einen Hash. Das funktioniert, bis zwei Clients gleichzeitig dieselbe Collection anfassen oder bis Sie fragen, was bei einem Failover passiert. In Zaris ist ein Hash ein Hash auf dem Server. Er liegt auf der Partition, die seinen Key besitzt, repliziert auf das Replikat dieser Partition und überlebt den Verlust eines Nodes genau so wie ein einfacher Key.

Zaris 2.0.0: Native Datenstrukturen, Streams und ein Redis-Protokoll-Frontend

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

Zaris 2.0.0 — Native Datenstrukturen, Streams und ein Redis-Protokoll-Frontend

Heute veröffentlichen wir Zaris 2.0.0 — das größte Release seit der allgemeinen Verfügbarkeit von Zaris und das erste mit einem Major-Versionssprung. Es macht aus Zaris, einem schnellen, replizierten Key/Value-Store, einen vollwertigen Datenstruktur-Server: native Hashes, Listen, Sets, Sorted Sets, Pub/Sub und Redis Streams, alle auf dieselbe Weise partitioniert und repliziert wie Ihre Keys bereits.

Und es öffnet die Tür für alle anderen. Jeder Node kann nun ein Redis-Protokoll-Frontend (RESP) bereitstellen, sodass eine Anwendung in Python, Ruby, Java, Go — jeder Sprache mit einem Redis-Client — auf Zaris zeigen und es als Drop-in nutzen kann, ohne natives SDK und ohne eine Zeile umzuschreiben.

Die Versionsnummer ist eine 2 und keine 1.x, und das hat einen Grund: 2.0.0 ändert das Wire-Protokoll. Lesen Sie den Upgrade-Hinweis unten, bevor Sie es ausrollen.

Jede Sprache, ein Store: Wie Zaris das Redis-Protokoll spricht

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

Jede Sprache, ein Store

Zaris ist ein verteilter Key/Value-Store, der nativ für .NET gebaut wurde. Seine erstklassigen Clients sprechen ein effizientes binäres Protokoll, und wenn Ihr Stack .NET ist, ist das der Pfad, den Sie wollen — echte Async-APIs, .NET-Typen, Koordinationsprimitive, Drop-ins für IDistributedCache und HybridCache.

Die meisten Systeme bestehen aber nicht nur aus .NET. Da gibt es einen Python-Dienst für Datenarbeit, einen Go-Sidecar, einen Ruby-Job-Runner, ein Node-Gateway. Sie alle auf einen neuen Client umzuschreiben, nur um einen neuen Store auszuprobieren, kommt nicht in Frage. Deshalb kann in 2.0.0 jeder Zaris-Node zusätzlich einen Redis-Protokoll-Listener (RESP2) bereitstellen: Richten Sie einen bestehenden Redis-Client darauf und nutzen Sie Zaris als Drop-in-Key/Value-Store, in jeder Sprache, ohne eine Zeile Client-Code zu ändern.

Dieser Beitrag beschreibt, wie dieses Frontend tatsächlich funktioniert — das Routing-Modell, das Datenmodell, die Failover-Modelle und genau, welche Befehle dabei und welche nicht dabei sind.

Lesezugriffe, die mit Ihren Cores skalieren

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

Der GET-Durchsatz von Zaris skaliert mit den Cores

Redis ist schnell. Es ist aber auch, konstruktionsbedingt, auf dem Datenpfad single-threaded: eine Event-Loop, ein Core, ein Befehl nach dem anderen. Das ist ein wirklich gutes Design — es macht Redis leicht nachvollziehbar und beseitigt eine ganze Kategorie von Nebenläufigkeitsfehlern. Aber es hat eine Obergrenze, die sich nicht mit Hardware kaufen lässt. Geben Sie einer Engine mit einer einzigen Event-Loop eine 4-Core-, eine 8-Core- oder eine 32-Core-Maschine, und der Lese-Durchsatz landet an derselben Stelle. Die zusätzlichen Cores bleiben ungenutzt.

Zaris geht den anderen Weg. Keys sind partitioniert, und jede Partition hat einen Besitzer, sodass Lesezugriffe auf verschiedene Keys auf verschiedenen Cores landen und gleichzeitig laufen. Das Ergebnis ist ein Durchsatz, der sich beim Hinzufügen von Cores bewegt — statt einer flachen Linie ein Anstieg.

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.