Funktionsweise
Diese Seite geht den tatsächlichen Nachrichtenfluss zwischen einem Client und dem Server (Cluster) durch, um zu erklären, wie Ticketing funktioniert. Die exakte, byte-genaue Spezifikation dessen, was über die Leitung geht, findest du unter Protokoll (API) und Protokoll (Cluster).
Gesamtstruktur
Dienste, die Nutzeranfragen entgegennehmen (etwa die Event-Server, die eine Ticket-Verkaufsöffnung bearbeiten), reihen sich für denselben Schlüssel beim Ticketing-Cluster ein, und nur der Server, der an der Reihe ist, fährt mit Arbeiten wie dem Verringern des Bestands oder der Sitzplatzvergabe fort.
Eine Sperre erwerben und freigeben
Der grundlegende Ablauf. Ein nicht gehaltener Schlüssel wird sofort vergeben; ein gehaltener Schlüssel wartet in der FIFO-Warteschlange, bis er an der Reihe ist. Wenn der Inhaber freigibt, wird die Sperre direkt und ohne erneuten Wettbewerb an die Spitze der Warteschlange übergeben — der nächste Wartende fährt sofort mit einem neuen Token fort, sodass die Sperre nie einen Moment lang leer steht und niemand sich vordrängeln kann.
leaseist ein Sicherheitsnetz. Stirbt ein Client oder vergisst er die Freigabe, holt sich der Server den Schlüssel zurück, sobald dielease-Dauer abgelaufen ist, und übergibt ihn an den nächsten Wartenden. Wähle sie großzügig — länger als die im schlimmsten Fall benötigte Zeit für deinen kritischen Abschnitt. v1 akzeptiert nur 1 bis 250 Sekunden; längere Arbeiten werden als ausdrücklich nicht unterstützt abgelehnt.waitist die Obergrenze dafür, wie lange ein Client wartet. Kommt er innerhalb dieser Zeit nicht an die Reihe, antwortet der Server mitT(Timeout) statt die Sperre zu vergeben, sodass niemals eine Sperre verloren geht.0bedeutet einen einzigen sofortigen Versuch ohne Einreihen. Unbegrenztes Warten gibt es nicht.- Versucht derselbe Client, einen Schlüssel erneut zu erwerben, den er bereits hält, reiht er sich genau wie jeder andere Wartende ein — dies ist keine reentrante Sperre.
Die vollständigen Regeln zum Serververhalten je Schlüsselzustand findest du unter Anfrage-×-Schlüsselzustand-Matrix, die Wertebereiche der Felder unter Feldbeschränkungen.
Fencing-Tokens
Selbst ein perfekter Lock-Server kann die Uhr eines Clients nicht kontrollieren. Ticketing allein kann den Fall des veralteten Inhabers nicht verhindern: ein Client, der eine Weile durch GC-Pausen oder Überlast eingefroren war, während er die Sperre hielt, dann aufwacht — ohne zu wissen, dass seine lease bereits abgelaufen ist — und seine Arbeit fortsetzt. Deshalb ist das token in jeder Acquire-Antwort eine u64-Ganzzahl, die garantiert bei jeder Vergabe steigt. Bei Finanzdaten oder persistenten Datenbanken müssen Vergleich und Aktualisierung des schlüsselbezogenen Fencing-High-Water-Werts mit dem eigentlichen Business-Write in derselben DB-Transaktion oder einem einzigen bedingten Write atomar erfolgen. Nur die Fencing-Zeile zuerst zu aktualisieren und den eigentlichen Write später auszuführen ist nicht sicher.
Die Monotonie gilt auch clusterweit — der Token-Zähler selbst wird per Konsens repliziert, sodass der neue Leader auch nach einem Leaderwechsel immer bei einer höheren Zahl als zuvor fortfährt. Das exakte Feldformat findest du unter Fencing-Token (Spezifikation).
Cluster — unterbrechungsfrei durch Raft-Konsens
Im Cluster-Modus teilen sich die Knoten einen einzigen Sperrenzustand per Raft-Konsens. Nur der Leader bearbeitet Client-Anfragen, und jede Zustandsänderung einer Sperre (Erwerb, Freigabe, Ablauf) wird erst finalisiert, nachdem eine Mehrheit der Knoten sie verzeichnet hat. Verbindest du dich mit einem Nicht-Leader-Knoten, erhältst du eine M-Antwort (verwiesen), die auf den Leader verweist.
- Stirbt der Leader, wählen die aktuellen Standardeinstellungen in etwa 2,3–2,5 Sekunden einen neuen Leader. Dasselbe logische Acquire darf innerhalb des verbleibenden
wait-Budgets nur fortgesetzt werden, wenn kein Request-Byte gesendet wurde. Ein gesendetes Acquire ohne bestätigte Antwort istIndeterminateund wird niemals automatisch erneut gesendet. - Selbst der
lease-Ablauf durchläuft den Konsens. Eine Sperre verschwindet erst, wenn der Leader den Ablaufbefehl committet, sodass leicht unterschiedliche Uhren zwischen Knoten den Sperrenzustand nie auseinanderlaufen lassen. - Verliert der Cluster seine Mehrheit (z. B. 2 von 3 Knoten ausgefallen), stoppt er lieber die Annahme von Schreibvorgängen, als riskant eine fehlerhafte Sperre zu vergeben (Sicherheit zuerst). Geht der flüchtige Prozesszustand von 2 aus 3 (oder 3 aus 5) Knoten verloren, darf diese Cluster-/Fencing-Domain weder wiederhergestellt noch unter derselben Identität automatisch gebootstrapt werden.
Weil die Mehrheit entscheidend ist, sind nur 3 oder 5 Knoten zulässig. Eine gerade Knotenzahl erhöht nur die Kosten, ohne die Fehlertoleranz zu verbessern, daher verweigert der Server mit einer solchen den Start.
| Knotenzahl | Unterbrechungsfrei | Tolerierte gleichzeitige Ausfälle | Anmerkungen |
|---|---|---|---|
| 1 | ✗ | — | Token-Monotonie nur für die Prozesslebensdauer garantiert; zum Schutz einer neustartbaren persistenten DB nicht unterstützt |
| 3 | ✓ | 1 | Die Standard-Konfiguration für Unterbrechungsfreiheit. Reicht für die meisten Fälle |
| 5 | ✓ | 2 | Redundanz bleibt sogar bestehen, während ein Knoten gewartet wird |
Die Frame- und Portregeln der Peer-RPCs findest du unter Protokoll (Cluster), das Verfahren zum Ersetzen einzelner Knoten unter unterbrechungsfreier Learner-Ersatz mit neuer NodeId.
Client-Verhalten
Die offiziellen Clients teilen sich das folgende Verhalten (sprachspezifische APIs findest du unter Bibliotheken).
- Hält im Hintergrund eine dauerhafte Verbindung pro Adresse. Bei einer einzelnen Adresse hält er zwei Verbindungen zu diesem Knoten, sodass ein kurzer Ausfall eines Sockets den Dienst nicht unterbricht.
- Wählt die Verbindung leader-zuerst, dann Round-Robin. Er merkt sich den zuletzt per
Mverwiesenen Leader und schickt nachfolgende Anfragen direkt an ihn. - Anfragen werden pipeline-verarbeitet. Die nächste Anfrage kann gesendet werden, ohne auf eine Antwort zu warten — wie Antworten den Anfragen zugeordnet werden, steht unter Regeln zur Antwortzuordnung.
- Eine abgebrochene Verbindung versucht mit exponentiellem Backoff weiter, sich neu zu verbinden (0,1 s bis maximal 3,2 s). Eine tote Verbindung zerstört das Broker-Objekt nicht — es erholt sich von selbst.
- Dasselbe logische Acquire wird intern nur erneut versucht, wenn kein Request-Byte gesendet wurde. Ein korreliertes
Bist ein sicheres Busy/Nicht-Erworben und geht ohne internen Retry sofort an den Aufrufer.Mist nur ein Leader-Hinweis für die nächste Verbindung; ohne owner/key begründet es kein erneutes Senden einer bereits gesendeten Pending-Anfrage. Ein gesendetes Acquire ohne bestätigte Antwort wird alsIndeterminategemeldet; der kritische Abschnitt darf nicht betreten werden. - Explizite Freigabe und Known-Token-Kompensation nutzen einen exakten owner/token/key-Abgleich und eine begrenzte dedizierte Queue. Retries enden an einer absoluten 5-Sekunden-Deadline ab Request/Enqueue, nicht am verbleibenden Lease. Ohne Erfolgsantwort wird eine explizite Freigabe weder als erfolgreich gemeldet noch angenommen; der serverseitige Lease bleibt das letzte Netz.
Verbindungen und Sicherheit
Jede Verbindung (Client oder Peer) wird in der Reihenfolge TCP → (TLS) → Challenge-Response-Authentifizierung aufgebaut. Der Client hasht die Nonce des Servers zusammen mit seinem Token, um zu antworten, sodass das Token niemals im Klartext über die Leitung gesendet wird, und eine frische Nonce bei jeder Verbindung schließt Replay-Angriffe aus. Die exakte Spezifikation findest du unter Auth-Handshake.
Anmerkung zur Konsistenz
- Der gegenseitige Ausschluss wird durch Konsens garantiert. Da jede Vergabe einen Mehrheits-Commit durchläuft, wird derselbe Schlüssel niemals zwei Inhabern gleichzeitig vergeben, selbst während einer Netzwerkpartitionierung oder eines Leaderwechsels.
- Persistente Datenbanken müssen Fencing erzwingen. Nur eine schlüsselbezogene High-Water- Bedingung, die mit dem geschützten Write in derselben Transaktion/demselben bedingten Write atomar ausgeführt wird, stoppt einen nach Lease-Ablauf erwachenden Client. Die Sperre ordnet die Arbeit; DB-Fencing blockiert den letzten veralteten Write.