Vom Gerät ins Event-Backbone
In vielen IoT-Landschaften stößt man auf eine vertraute Ausgangslage: Unzählige Sensoren und Edge-Geräte sprechen MQTT – schlank, einfach, effizient. Dazu kommen gewachsene Infrastrukturen mit etablierten Brokern wie Mosquitto, EMQX, HiveMQ oder den MQTT-Stacks diverser Industrie- und Gateway-Hersteller. Diese Broker sind tief in bestehende Edge-Topologien integriert, oft hochverfügbar betrieben und Bestandteil sicherheitskritischer Kommunikationspfade.
Gleichzeitig entsteht im Backend zunehmend der Wunsch nach Streaming, Persistenz, Skalierung, Rückverfolgbarkeit, Multi-Tenancy und modernen Auswertungsmöglichkeiten – etwas, das klassische MQTT-Broker nur teilweise oder gar nicht leisten können.
Die Frage liegt daher nahe:
Warum nicht MQTT-Nachrichten direkt in Apache Pulsar streamen – ohne die bestehende MQTT-Infrastruktur umzubauen?
Genau aus diesem Gedanken entstand pulsar-iotbridge: Ein kompaktes Go-Tool, das sich an einen bestehenden MQTT-Broker anhängt, dessen Topics abonniert und alle eingehenden Nachrichten in eine saubere, konsistente Pulsar-Namensstruktur spiegelt.
So bleibt die vorhandene MQTT-Landschaft unverändert, während im Backend ein modernes, skalierbares Event-System entsteht.
Motivation
MQTT ist hervorragend für Gerätekommunikation geeignet, aber nur bedingt für Backend-Verarbeitung und Analyse. Dagegen bietet Apache Pulsar:
- Topics mit Aufbewahrung (Retention)
- horizontale Skalierung
- Subskriptionsmodelle für Echtzeit und Replays
- ein sauberes Multi-Tenant-Modell
- Backlogs, DLQs, Compaction, Geo-Replikation …
Kurz: MQTT für die Edge, Pulsar für das Backend – zwei Welten, die sich optimal ergänzen.
Pulsar ist für große Streaming-Workloads optimiert, nicht für stromsparende Edge-Devices. MQTT hingegen ist für kleine Geräte gemacht, unterstützt QoS, ist bandbreitenschonend und leichtgewichtig.
Die Kombination aus beidem bietet das Beste aus zwei Welten.
Idee
Die Grundidee von pulsar-iotbridge ist bewusst minimalistisch:
- Mit einem MQTT-Broker verbinden
- Alle gewünschten Topics abonnieren (standardmäßig:
#) - Jede eingehende Nachricht einer Namensstruktur zuordnen
- Das Payload unverändert im zugehörigen Pulsar-Topic veröffentlichen
Aus einem MQTT-Topic wie:
dt/device123/temperature
wird ein Pulsar-Topic wie:
persistent://public/mqtt_ingest/dt/device123/temperature
Ohne Transformation, ohne Magie – einfach ein Event-Transport zwischen zwei Welten.
- keine semantische Interpretation
- keine Datenanreicherung
- keine Schemas
- keine Transformationen
Sie ist bewusst „stupid simple“. Genau das macht sie robust.
Umsetzung
Der Fokus des Projekts liegt nicht auf möglichst vielen Features, sondern auf einer nachvollziehbaren, wartbaren und sicheren Architektur.
Pulsar-iotbridge setzt auf zwei bewährte Bausteine:
1. MQTT-Client (Paho)
Die Bridge nutzt die etablierte Go-Implementation von Eclipse Paho für MQTT. Sie verbindet sich als Client, abonniert die gewünschten Topics und erhält jede Nachricht über einen Callback.
2. Apache Pulsar Go-Client
Für das Backend nutzt die Bridge den nativen Pulsar-Go-Client. Dieser bietet:
- effizientes Batching
- LZ4-Kompression
- asynchrones Publishing
- stabile Verbindungshandhabung
Ein Publisher wird pro Pulsar-Topic erzeugt und wiederverwendet. Damit entsteht ein klar definierter Pfad pro Topic – strukturiert und sauber isoliert.
Go eignet sich hervorragend für IO-intensive Tools:
- kleine, statische Binaries
- schnelle Startup-Zeiten
- sehr gute Parallelisierung
- geringer Memory-Footprint
Ideal für leichtgewichtige Integrationskomponenten.
Architektur aus der Vogelperspektive
[ IoT-Device ] --MQTT--> [ MQTT-Broker ] --> [ pulsar-iotbridge ]
|
| Pulsar-Event
v
[ Apache Pulsar ]
|
v
[ Analytics / Backend ]
Lokaler Test mit Podman
Mit wenigen Zeilen lässt sich ein Pulsar-Standalone starten:
podman run -it --rm \
-p 6650:6650 \
-p 8080:8080 \
docker.io/apachepulsar/pulsar:4.0.7 \
bin/pulsar standalone
Parallel dazu kann ein MQTT-Broker laufen, z. B. Mosquitto.
Starten der Bridge
./pulsar-iotbridge run \
--mqtt-url tcp://localhost:1883 \
--pulsar-url pulsar://localhost:6650 \
--tenant public \
--namespace mqtt_ingest \
--workers 8
Nun werden alle MQTT-Nachrichten aus allen Topics abgefangen und nach Pulsar gespiegelt.
pulsar-iotbridge bringt von Haus aus einen kleinen Prometheus-Endpoint (/metrics) mit.
Damit lassen sich zentrale Betriebsgrößen direkt überwachen – ohne zusätzliche Instrumentierung.
Erfasst werden u. a.:
- eingehende MQTT-Nachrichten pro Topic
- erfolgreich veröffentlichte Pulsar-Nachrichten
- ausstehende (pending) Pulsar-Publishes
- Fehlerzähler pro Pulsar-Topic
- gedroppte Nachrichten bei Überlast
So behält man jederzeit im Blick, ob die Bridge unter Last sauber arbeitet, ob Topics „heiß laufen“ oder ob Eingangs-Queues an ihre Grenzen kommen. Ideal für Dashboards, Alerting und Capacity-Planung.
Verifizieren
Empfangsseite in Pulsar:
./pulsar-cli consumer --regex -t 'persistent://public/mqtt_ingest/.*' -s debug
MQTT-Test:
mosquitto_pub -t dt/dev1/temp -m "22.4"
Wenige Millisekunden später taucht die Nachricht im Pulsar-Consumer auf.
Warnhinweise und Limitationen
Durch den Worker-Pool und asynchrones Publishing kann die Reihenfolge von Nachrichten eines MQTT-Topics im Pulsar-Topic abweichen.
Wer strikte Ordering-Semantik benötigt, sollte:
- die Bridge mit
--workers 1betreiben, oder - einen Serialisierungsmechanismus pro Topic einführen, oder
- direkt Pulsar-IO bzw. andere integrierte Mechanismen nutzen.
Die Eingangsqueue ist bewusst begrenzt. Ist sie voll, werden Nachrichten verworfen, statt Backpressure auf die Geräte auszuüben.
Das schützt die Stabilität des Gesamtsystems – aber nicht jede Anwendung toleriert Drops.
Alternative: Pulsar-MOP (MQTT-on-Pulsar)
Statt eine externe Bridge zu betreiben, erweitert Pulsar-MOP den Pulsar-Broker selbst um einen vollständigen MQTT-Server. Geräte sprechen weiterhin MQTT — landen aber direkt im Pulsar-Ökosystem.
Vorteile:
- keine separate Bridge oder zusätzliche Infrastruktur notwendig
- Geräte senden direkt an Pulsar → kein Medienbruch
- vollständige native MQTT-Kompatibilität (QoS, Sessions, Retain etc.)
- Daten landen sofort in Pulsar-Topics und profitieren von Retention, Backlog & Replays
Nachteile:
- ersetzt den bestehenden MQTT-Broker vollständig
- höherer operativer Footprint (Pulsar muss auch MQTT-Workloads stemmen)
- für ressourcenbeschränkte Edge-Szenarien oft zu schwergewichtig
- weniger entkoppelt als eine externe Bridge (Monolithisierungstendenz)
Projektseite: https://github.com/streamnative/mop
Pulsar-MOP erweitert den Pulsar-Broker um einen vollständig integrierten MQTT-Server: Geräte sprechen weiterhin MQTT – die Nachrichten landen jedoch direkt in Pulsar.
Fazit
pulsar-iotbridge ist ein kleines, aber wirkungsvolles Werkzeug, um bestehende MQTT-Landschaften in die Ereigniswelt von Apache Pulsar zu heben – ohne Geräte umzubauen, ohne große Architekturveränderungen, ohne schwergewichtige Connector-Infrastruktur.
pulsar-iotbridge ist bewusst als Proof of Concept umgesetzt: einfach, nachvollziehbar, ohne unnötige Magie – und mit klar sichtbaren Grenzen.
Der Fokus liegt auf Verständlichkeit, nicht auf Vollständigkeit. Aktuelle Limitationen sind u. a.:
- keine garantierte Nachrichtenreihenfolge (parallelisierte Worker, async Publish)
- Smile-but-drop-Verhalten bei Überlast statt Backpressure
- keine Schema-Unterstützung, keine Transformationen
- kein Zero-Copy-Pfad und bewusst minimalistische Fehlerbehandlung
Trotzdem: Der Code läuft, ist transparent und zeigt den Ansatz auf praktische Weise.
- Projekt-Repository: pulsar-iotbridge
Bildnachweis: Das Pulsar-Logo ist eine eingetragene Marke der Apache Software Foundation. Verwendung im Rahmen redaktioneller Berichterstattung gemäß den offiziellen Richtlinien.