Pulsar Sentinel – Self-Fencing für Apache Pulsar-Cluster

Pulsar Sentinel – Self-Fencing für Apache Pulsar-Cluster
By Matthias Petermann / on 08.10.2025

Motivation

Verteilte Systeme wachsen schnell – und mit jeder neuen Komponente steigen Komplexität und das Risiko unkontrollierter Wechselwirkungen. Gerade bei Messaging-Plattformen wie Apache Pulsar zeigt sich das besonders deutlich, wenn mehrere Standorte über Geo-Replikation verbunden sind.

Fällt eine Verbindung aus oder gerät ein Standort aus dem Takt, droht eine der kritischsten Situationen verteilter Systeme: ein Split-Brain. Zwei Clusterhälften nehmen weiter Schreiboperationen an, ohne voneinander zu wissen – mit potenziell widersprüchlichen Daten und aufwendiger Nachsynchronisierung.

Aus genau diesem Szenario heraus entstand Pulsar Sentinel: ein kleines, in Go geschriebenes Werkzeug, das Pulsar-Cluster überwacht, Quorum-Verluste erkennt und bei Bedarf gezielt Self-Fencing auslöst – automatisch, nachvollziehbar und ohne Abhängigkeiten von externen Komponenten.

ℹ️ Ausgangspunkt: Geo-Replikation als Hot-Standby

Der Impuls für Pulsar Sentinel entstand aus einem konkreten Einsatzszenario, bei dem Geo-Replikation nicht zur klassischen Datenverteilung, sondern zur 24/7-Bereitstellung eines Hot-Standby-Clusters genutzt wird.

In dieser Architektur müssen Nachrichtenreihenfolge, Request/Reply-Semantik und Zustandskonsistenz auch bei Standortausfall oder Netzwerksegmentierung gewahrt bleiben.

Gerade hier können Split-Brain-Zustände schwerwiegende Folgen haben – doppelte Verarbeitung, widersprüchliche Events und fehlerhafte Wiederherstellung. Sentinel adressiert genau diesen Punkt: gezielte Selbstbegrenzung, bevor schwerwiegende Inkonsistenzen entstehen.


Architektur und Grundprinzip

Pulsar Sentinel folgt einer klaren, deterministischen Struktur:

  • Kommunikation über UDP-Heartbeats zwischen den Knoten
  • periodische HTTP-Healthchecks des lokalen Brokers
  • Quorum-Überwachung nach Prioritätsgruppen
  • Fencing-Mechanismus bei Quorum-Verlust oder Split-Brain-Gefahr

Jeder Knoten sendet regelmäßig Heartbeats mit seinem Status (Healthy, Priority, Timestamp) und verwaltet die eingehenden Statusinformationen der anderen Nodes lokal. Auf dieser Basis entscheidet das Tool, ob der Cluster noch im Gleichgewicht ist.

ℹ️ Self-Fencing: Schutz durch Rückzug

Self-Fencing bezeichnet den kontrollierten Rückzug eines Knotens aus dem Cluster, sobald er erkennt, dass seine Sicht auf das Gesamtsystem nicht mehr konsistent ist.

Das Ziel ist nicht maximale Verfügbarkeit um jeden Preis, sondern Kohärenz und Schutz vor Divergenz – etwa, wenn zwei Standorte gleichzeitig glauben, „führend“ zu sein.

Pulsar Sentinel führt Self-Fencing nach einer konfigurierbaren Grace Period und mit Cooldown zwischen Aktionen aus. So bleibt das Verhalten vorhersehbar und sicher reproduzierbar.


Komponenten im Überblick

1. Broker-Healthcheck

Der lokale Pulsar-Broker wird regelmäßig über den Endpunkt /admin/v2/brokers/health geprüft. Das Ergebnis fließt direkt in den Heartbeat-Status ein. Optional kann eine Authentifizierung über den Header Authorization: Bearer <token> erfolgen.


2. Heartbeat-Mechanismus

Jeder Node sendet in festen Intervallen UDP-Pakete mit seinem Status an ein Broadcast- oder Multicast-Ziel. Eingehende Pakete werden als JSON-Strukturen geparst und in Maps gespeichert (peers, peersTS), die alle bekannten Cluster-Knoten abbilden.

Die Nachrichten enthalten:

  • Typ
  • Node-ID
  • Zeitstempel
  • Statusdaten (Priorität, Health)

3. Quorum-Logik

Etwa alle zehn Sekunden bewertet Sentinel den Zustand des Clusters:

  • Hält die eigene Prioritätsgruppe noch Quorum?
  • Existiert bereits eine höher priorisierte Gruppe mit stabilem Quorum?

Wenn eine dieser Bedingungen nicht erfüllt ist, startet der Fencing-Timer (Grace Period + Cooldown), um Inkonsistenzen zu vermeiden.


4. HTTP-Health-Endpoint

Ein integrierter HTTP-Server (Standardport 3000) kombiniert lokalen Brokerstatus und Cluster-Quorum zu einer konsistenten Bewertung:

GET / → 200 OK     # healthy
GET / → 503 FAIL   # unhealthy

Dieser Endpoint eignet sich ideal als Healthcheck für Upstream-Loadbalancer.


Steuerung und Parametrisierung

Das Verhalten lässt sich über CLI-Flags oder Umgebungsvariablen steuern.

Flag Beschreibung
--priority Node-Priorität (1 = höchste)
--timeout Zeit, bis ein Node als „verloren“ gilt
--grace-period Wartezeit vor Fencing-Aktion
--fencing-cooldown Pause zwischen Fencing-Vorgängen
--multicast Optionale Multicast-Gruppe statt Broadcast
--healthcheck URL des Broker-Healthchecks

Beispiel:

./pulsar-sentinel --priority 2 --multicast 239.0.0.1 --grace-period 30s

Fencing-Mechanismus

Wird ein Knoten durch die Quorum- oder Healthcheck-Logik als kritisch erkannt, führt Sentinel die Funktion fenceNode() aus. Standardmäßig wird nur geloggt – kein destruktiver Eingriff.

In produktiven Setups kann ein eigenes Kommando über die Umgebungsvariable FENCING_COMMAND definiert werden, z. B.:

export FENCING_COMMAND="systemctl restart pulsar-proxy"

So lässt sich ein Node gezielt und kontrolliert aus dem Verbund nehmen.


Integration und Erweiterbarkeit

Pulsar Sentinel läuft derzeit vollständig autark und benötigt keine zentrale Datenbank oder Control Plane. Alle Zustände werden lokal im Speicher verwaltet und regelmäßig aktualisiert – damit funktioniert das Tool stabil und nachvollziehbar auch in isolierten Umgebungen.

Aktuell ist Sentinel für produktiven Einsatz in geschlossenen Cluster-Setups ausgelegt, etwa auf dedizierten Nodes oder in Private-Cloud-Umgebungen.

Geplant sind Erweiterungen für:

  • signierte Healthchecks, um Zustände kryptografisch abzusichern,
  • einen Prometheus-kompatiblen Metrics-Endpoint,
  • sowie zusätzliche Nachrichtentypen (alerts, sync) für feinere Steuerung.

Diese Punkte sind bewusst als nächste Evolutionsschritte vorgesehen – die Basis steht, der Ausbau ist klar umrissen.


📝 Repository & Rust-Prototyp

Der Quellcode ist öffentlich verfügbar unter: 🔗 pulsar-sentinel (Go-Version)

Eine funktionell äquivalente Proof-of-Concept-Version in Rust existiert ebenfalls: 🔗 pulsar-sentinel-rs

Die Rust-Variante demonstriert dasselbe Konzept mit Ownership- und Concurrency-Sicherheit, wurde jedoch zurückgestellt, da sich der Buildprozess in Go als deutlich robuster und portabler erwiesen hat. Hauptgrund war die Komplexität beim Erzeugen statisch gelinkter Binaries: Rust zog über zahlreiche Abhängigkeiten hinweg die OpenSSL-C-Library ein, was eine vollständig unabhängige Distribution erschwerte.


Fazit

Pulsar Sentinel ist kein Framework, sondern ein betriebliches Sicherheitsnetz – ein Werkzeug, das erkennt, wenn ein Cluster aus dem Takt gerät, und rechtzeitig handelt, bevor Inkonsistenzen entstehen.

Erkenntnis: Stabilität in verteilten Systemen entsteht nicht durch immer neue Schichten, sondern durch einfache, überprüfbare Mechanismen, die im Ernstfall zuverlässig das Richtige tun.