Thema: distributed-systems
-
Verteiltes Tracing in Umrissen: Spans, Eltern-Kennungen und W3C Trace Context
Ein Trace ist ein Baum aus Spans, jeder mit Trace-Kennung, eigener Span-Kennung, Eltern-Span-Kennung, Zeitstempeln, Attributen und Status; der W3C-Header traceparent trägt Trace-Kennung, Eltern-Kennung und ein Sampled-Flag über Prozessgrenzen, und ein Dienst, der beide Header nur weiterreicht, hält Traces trotzdem zusammen.
-
Was ein Raft-Cluster garantiert: Mehrheiten, ein Leader und linearisierbare Lesevorgänge
Konsenssysteme wie etcd (Raft) lassen eine Mehrheit der Server sich auf ein geordnetes Log einigen; sie bleiben bei beliebig vielen Ausfällen korrekt, kommen aber nur voran, solange eine Mehrheit erreichbar ist. Linearisierbare Lesevorgänge laufen über den Konsens und kosten Latenz; serialisierbare Lesevorgänge werden lokal bedient und können veraltet sein.
-
Idempotente Operationen und sichere Wiederholungen entwerfen
Eine Operation ist idempotent, wenn ihre mehrfache Ausführung dieselbe Wirkung hat wie eine einzelne; RFC 9110 legt das für HTTP-Methoden fest, und ein Idempotency-Key-Header überträgt die Eigenschaft auf POST. Schlüssel samt Fingerabdruck und Ergebnis speichern, Konflikte mit 409 und 422 melden, Schlüssel nach dokumentierter Frist löschen.
-
Sagas: mehrstufige Workflows über mehrere Services mit Kompensation statt Rollback
Eine Saga ist eine Folge lokaler Transaktionen in verschiedenen Services, von denen jede die nächste auslöst; schlägt ein Schritt fehl, werden frühere Schritte durch vom Entwickler geschriebene Kompensationstransaktionen rückgängig gemacht. Sagas stellen Konsistenz ohne verteilte Transaktionen her, geben dafür aber Isolation auf, sodass Zwischenzustände sichtbar sind und Kompensationen bewusst entworfen statt vorausgesetzt werden müssen.
-
Tail-Latenz-Verstärkung: wenn eine Anfrage auf die langsamste von hundert wartet
Eine Anfrage, die an N Backends verteilt wird, ist so langsam wie die langsamste Antwort, sodass eine pro Backend nur 1-von-100 langsame Antwort etwa 63 % der hundertfach verteilten Anfragen langsam macht. Das p99 des Blatts wird zum Median der Wurzel; die Abhilfen sind weniger Blätter, Hedged- oder Tied-Requests nach einer perzentilbasierten Verzögerung, Deadlines mit Teilergebnissen, und das Beseitigen der Ursachen der Blatt-Tails.
-
Events zuverlässig veröffentlichen mit einer transaktionalen Outbox
Das Event in derselben Datenbanktransaktion wie die Zustandsänderung in eine Outbox-Tabelle schreiben und es dann von einem separaten Relay an den Broker weitergeben lassen. Das beseitigt das Zeitfenster, in dem Zustand gespeichert, aber das Event verloren ist (oder umgekehrt), zum Preis von At-least-once-Zustellung und einem zu betreibenden Relay.
-
Bulkheads pro Abhängigkeit halten unabhängige Endpunkte verfügbar, wenn eine Abhängigkeit stockt
Hypothese: Ruft ein Dienst mehrere Abhängigkeiten aus einem gemeinsamen Pool von Threads oder Nebenläufigkeits-Slots auf, reisst eine Abhängigkeit, die langsam wird (nicht ausfällt), unabhängige Endpunkte mit sich, sobald der Pool erschöpft ist; gibt man jeder Abhängigkeit einen eigenen begrenzten Pool, bleiben die anderen Endpunkte während desselben Stockens nahe an ihrer normalen Latenz und Fehlerrate.
-
Read-Replikas und Replikationsverzögerung: Wie veraltete Lesezugriffe aussehen und wie man sie begrenzt
Eine Streaming-Replika wendet das Log des Primärservers mit einer gewissen Verzögerung an, sodass ein Lesezugriff unmittelbar nach einem Schreibzugriff diesen möglicherweise nicht sieht. Lesezugriffe danach leiten, wie viel Veraltung der jeweilige Aufrufer toleriert, synchrone Replikationsmodi nur dort einsetzen, wo ihre Latenz akzeptabel ist, und verstehen, dass das Nachspielen des Logs lange Abfragen auf der Replika abbrechen kann.
-
gRPC-Grundlagen: Protobuf-Verträge, Streaming und Einsatzbereich
gRPC ruft Methoden auf, die in einer .proto-Datei definiert sind, mit Protocol Buffers als Schnittstellendefinition und Übertragungsformat; es bietet unäre und Streaming-Aufrufe, Deadlines, Metadaten sowie eine feste Menge an Statuscodes über HTTP/2. Es passt zu Service-zu-Service-Kommunikation und mobilen Backends; Browser benötigen gRPC-Web, und öffentliche Integratoren erwarten in der Regel JSON über HTTP.
-
Konsistentes Hashing: stabile Schlüssel-Platzierung, wenn Knoten kommen und gehen
Einen Schlüssel modulo der Knotenanzahl zu hashen, ordnet die meisten Schlüssel neu zu, sobald ein Knoten hinzugefügt oder entfernt wird. Konsistentes Hashing platziert Knoten und Schlüssel auf einem Ring, sodass sich nur die Schlüssel neben dem geänderten Knoten verschieben; virtuelle Knoten gleichen die Last aus, und tabellenbasierte Varianten wie Maglev tauschen etwas Platzierungsstabilität gegen schnelleres Nachschlagen ein.
-
Verteiltes Tracing im Überblick: Spans, Parent-IDs und die Weitergabe des W3C-Trace-Kontexts
Ein Trace ist ein Baum aus Spans, jeder mit einer Trace-ID, einer eigenen Span-ID, einer Parent-Span-ID, Zeitstempeln, Attributen und einem Status; der W3C-Header traceparent trägt Trace-ID, Parent-ID und ein Sampled-Flag über Prozessgrenzen hinweg, und ein Dienst, der beide Header nur weiterleitet, hält Traces trotzdem intakt.
-
CAP und PACELC als Entscheidungshilfen statt als Schlagworte
CAP verbietet nur einen einzigen Winkel des Entwurfsraums: perfekte Verfügbarkeit und linearisierbare Konsistenz, während eine Netzwerkpartition andauert. PACELC ergänzt den alltäglichen Zielkonflikt zwischen Latenz und Konsistenz, wenn keine Partition vorliegt. Als Fragen statt als Etiketten verwendet, helfen beide dabei, pro Operation zu entscheiden, wo ein System veraltete Daten zurückgeben darf und wo es sich abstimmen muss.
-
Backpressure und begrenzte Warteschlangen: die langsamste Stufe das Tempo vorgeben lassen
Eine unbegrenzte Warteschlange verwandelt Überlast in Speichererschöpfung und unbegrenzte Latenz. Backpressure bedeutet, dass der Konsument dem Produzenten mitteilt, wie viel er verarbeiten kann, von der Demand in Reactive Streams bis zu einem write(), das in Node.js false zurückgibt; eine begrenzte Warteschlange mit einem definierten Verhalten bei Überfüllung ist das Minimum, das jede Dienststufe benötigt.
-
Which overload signal should a small service shed load on: queue wait, in-flight count or CPU?
Open question: guidance lists CPU, latency, queue length and thread count as possible triggers for load shedding and calls the choice service-specific. For a service with a few instances and no global quota system, which signal, threshold and priority rule have teams actually kept in production, and how did they tune them?
-
Distributed locks and leader leases: expiry, fencing tokens and what a lock cannot promise
A distributed lock is a lease that expires; a process paused by garbage collection, CPU contention or a delayed network can keep acting after its lease has passed to someone else. Only a monotonically increasing fencing token checked by the protected resource makes such a lock safe for correctness, and a lock used merely to avoid duplicate work needs less.
-
Logical clocks: Lamport timestamps, vector clocks and hybrid clocks
Wall clocks on different machines disagree, so ordering events by timestamp loses updates. Lamport timestamps give an order consistent with causality, vector clocks additionally detect concurrent updates, and hybrid logical clocks keep a value close to wall time while preserving causal order.
-
Circuit breakers: failing fast when a dependency is down or slow
A circuit breaker counts failures and slow calls to a dependency; above a threshold it opens and rejects calls immediately, then lets a few trial calls through (half-open) before closing again. It protects the caller's threads and gives the dependency room to recover, but only with sensible windows, a fallback and a timeout underneath.
-
At-most-once, at-least-once and exactly-once delivery
Messaging systems deliver a message at most once (may lose), at least once (may duplicate) or effectively exactly once (deduplicated by the consumer); at-least-once plus idempotent consumers is the practical default, and 'exactly once' is a property of the whole pipeline, not of the broker.
-
Deletion pipelines across services, derived stores and backups
Model deletion of one person's data as a job with a state per store in the data map: fan out an event, require each owning service to report done with counts, handle versioned object storage and derived stores explicitly, bound how long backups keep the data or destroy per-subject keys, and keep a suppression list so restores can re-delete.
Maschinenlesbar: JSON