MQTT vs Kafka ist eine der häufigsten Architekturfragen im IoT, und die ehrliche Antwort lautet: Beide lösen unterschiedliche Hälften des Problems. MQTT holt Daten von Tausenden kleinen, zeitweise verbundenen Geräten; Kafka speichert, wiederholt und verarbeitet große Event-Ströme innerhalb Ihrer Datenplattform. Dieser Leitfaden vergleicht beide, erklärt, wo jedes an seine Grenzen stößt, und zeigt ein funktionierendes Muster, um Daten mit einem Consumer-Dienst unter Ihrer Kontrolle von einem MQTT-Broker nach Kafka zu übertragen.
Zwei Werkzeuge für zwei Aufgaben
MQTT ist ein schlankes Publish/Subscribe-Protokoll. Geräte öffnen eine TCP-Verbindung zu einem Broker, publizieren auf hierarchische Topics und abonnieren die Topics, die sie brauchen. Der Broker routet Nachrichten in Echtzeit, hält den letzten retained Wert pro Topic, puffert QoS-1- und QoS-2-Nachrichten für getrennte persistente Sessions und publiziert einen Last Will, wenn ein Gerät wegfällt. Es ist für eingeschränkte Clients und unzuverlässige Netze entworfen. Wenn es neu für Sie ist, ist was ein MQTT-Broker tut ein guter Einstieg.
Apache Kafka ist ein verteiltes Append-only-Commit-Log. Produzenten schreiben Records in partitionierte Topics, Kafka speichert sie dauerhaft für eine konfigurierbare Aufbewahrungsdauer, und Consumer-Gruppen lesen in ihrem eigenen Tempo und können zurückspulen, um die Historie erneut zu verarbeiten. Es ist für Backend-Dienste in zuverlässigen Netzen entworfen, die große Event-Mengen zwischen Systemen bewegen, mit Ökosystem-Werkzeugen für Stream Processing und Konnektoren zu Datenbanken und Data Lakes.
Die Verwirrung entsteht durch das gemeinsame Vokabular. Beide haben „Topics“, beide haben Produzenten und Konsumenten, und beide werden als Messaging-Systeme bezeichnet. Doch ein MQTT-Topic ist eine Routing-Adresse, die spontan und in Tausenden Varianten von Ebenen entstehen kann, während ein Kafka-Topic ein dauerhaftes, partitioniertes Log ist, das Sie bewusst bereitstellen.
MQTT vs. Kafka im Überblick
| Aspekt | MQTT | Apache Kafka |
|---|---|---|
| Hauptzweck | Gerätekonnektivität und Echtzeit-Routing | Dauerhaftes Event-Log und Stream Processing |
| Typische Clients | Mikrocontroller, Gateways, mobile Apps, Browser | Backend-Dienste, Stream-Prozessoren, Konnektoren |
| Verbindungen | Sehr viele, überwiegend inaktive Verbindungen | Weniger Verbindungen mit hohem Durchsatz |
| Topics | Hierarchisch, dynamisch, Wildcard-Subscriptions | Flache Namen, bereitgestellt, partitioniert |
| Speicherung | Retained letzter Wert pro Topic, Session-Queues | Vollständige Historie für die Aufbewahrungsdauer |
| Replay | Nein (nur der retained letzte Wert) | Ja, Konsumenten können zu jedem Offset springen |
| Zustellung | QoS 0, 1, 2 pro Nachricht | Acks pro Produzent, Offsets pro Consumer-Gruppe |
| Reihenfolge | Pro Topic und Client-Session | Pro Partition |
| Client-Footprint | Kilobytes, läuft auf einem ESP32 | Schwere Client-Bibliotheken, JVM oder librdkafka |
| Netzannahmen | Verlustbehaftet, hohe Latenz, NAT, Mobilfunk | Zuverlässiges Rechenzentrums- oder Cloud-Netz |
| Gerätefunktionen | Keep Alive, Last Will, retained Zustand | Keine |
| Browser-Unterstützung | MQTT über WebSocket | Nicht direkt |
Warum Geräte nicht direkt mit Kafka sprechen sollten
Technisch ist es möglich, einen Kafka-Producer auf einem Gateway zu betreiben, doch für Geräteflotten geht das selten gut:
- Gewicht des Clients. Kafka-Clients brauchen weit mehr Speicher und CPU, als ein Mikrocontroller hat, und setzen stabile Verbindungen zu mehreren Brokern voraus.
- Verbindungsmodell. Kafka ist für eine überschaubare Zahl geschäftiger Produzenten gebaut, nicht für Zehntausende Geräte, die alle paar Sekunden über wackelige Verbindungen einen Messwert senden.
- Keine Gerätesemantik. Es gibt keinen Last Will, keine Offline-Erkennung per Keep Alive und keinen retained letzten bekannten Wert pro Gerät.
- Befehle an Geräte. Kafka-Konsumenten pullen; es gibt keinen natürlichen Weg, einen Befehl an ein bestimmtes Gerät hinter NAT zu pushen.
- Angriffsfläche. Kafka-Listener für Geräte ins Internet zu stellen bedeutet, Zugangsdaten und ACLs pro Gerät auf einer Infrastruktur zu verwalten, die für den Betrieb in einem privaten Netz gedacht ist.
Warum MQTT allein keine Datenplattform ist
MQTT hat die umgekehrten Lücken. Ein Broker routet Nachrichten; er bewahrt keine Historie auf. Ist Ihr Analysejob eine Stunde lang ausgefallen, sind die verpassten Messwerte verloren, sofern keine persistente Session sie gehalten hat, und Session-Queues sind kein Langzeitspeicher. Sie können die Daten der letzten Woche nicht durch einen neuen Algorithmus erneut abspielen, und Sie können im Broker weder Streams verknüpfen noch Zeitfenster berechnen. Genau darin sind Kafka und sein Stream-Processing-Ökosystem gut.
Das Muster: MQTT am Edge, Kafka im Kern
Die Architektur, auf die sich die meisten Teams einpendeln, sieht so aus:
- Geräte und Gateways publizieren an einen MQTT-Broker, zum Beispiel auf
connectmq/factory1/production/line1/cnc1/telemetry. - Ein oder mehrere Consumer-Dienste abonnieren die relevanten Topic-Filter.
- Diese Dienste validieren, reichern an und versehen jede Nachricht mit einem Schlüssel und produzieren sie dann in ein Kafka-Topic wie
iot.telemetry, typischerweise mit der Geräte-ID als Schlüssel, damit die Reihenfolge pro Gerät innerhalb einer Partition erhalten bleibt. - Stream-Prozessoren, Sinks und Analysen lesen aus Kafka.
- Befehle fließen in die Gegenrichtung: Ein Dienst konsumiert ein Kafka-Befehls-Topic und publiziert auf das MQTT-Befehls-Topic des Geräts.
ConnectMQ enthält keine integrierte Kafka-Bridge, daher ist die Verbindung zwischen beiden immer eine Komponente, die Sie selbst betreiben: entweder Ihr eigener Consumer-Dienst, wie unten gezeigt, oder ein fertiger MQTT-Source-Connector für Kafka Connect, der so konfiguriert ist, dass er Ihren Broker als normaler MQTT-Client abonniert. Beide Ansätze behandeln den Broker als Standard-MQTT-Endpunkt, was die Integration portabel hält.
Einen Consumer-Dienst von MQTT zu Kafka bauen
Der folgende Python-Dienst abonniert ConnectMQ mit einer Shared Subscription, sodass Sie mehrere Instanzen betreiben können und der Broker die Last zwischen ihnen aufteilt, und produziert jede Nachricht mit confluent-kafka nach Kafka. Shared Subscriptions erfordern MQTT 5 und sind ab dem kostenpflichtigen Serverless-Plan verfügbar.
pip install "paho-mqtt>=2.0" confluent-kafka
import json
import ssl
import signal
import sys
import paho.mqtt.client as mqtt
from confluent_kafka import Producer
MQTT_HOST = "broker.connectmq.com"
MQTT_FILTER = "$share/kafka-bridge/connectmq/factory1/+/+/+/telemetry"
KAFKA_TOPIC = "iot.telemetry"
producer = Producer({
"bootstrap.servers": "localhost:9092",
"enable.idempotence": True,
"linger.ms": 20,
})
def delivery_report(err, record):
if err is not None:
print(f"Kafka delivery failed for key {record.key()}: {err}")
def on_connect(client, userdata, flags, reason_code, properties):
print("MQTT connected:", reason_code)
client.subscribe(MQTT_FILTER, qos=1)
def on_message(client, userdata, msg):
try:
payload = json.loads(msg.payload)
except json.JSONDecodeError:
print("skipping non-JSON payload on", msg.topic)
return
levels = msg.topic.split("/")
device_id = levels[-2] # z. B. cnc1
record = {"topic": msg.topic, "device": device_id, "data": payload}
producer.produce(KAFKA_TOPIC, key=device_id,
value=json.dumps(record), callback=delivery_report)
producer.poll(0)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.on_message = on_message
def shutdown(*_):
client.disconnect()
producer.flush(10)
sys.exit(0)
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
client.connect(MQTT_HOST, 8883, keepalive=30)
client.loop_forever()
Einige Produktionsdetails sind wichtiger als der Code selbst:
- Gegendruck (Back-Pressure). Ist Kafka nicht verfügbar, wirft
produceirgendwannBufferError, sobald sich die lokale Queue füllt. Entscheiden Sie, ob Sie blockieren, QoS-0-Daten verwerfen oder MQTT-Nachrichten nicht mehr bestätigen. paho bestätigt QoS-1-Nachrichten automatisch, nachdem der Callback zurückkehrt; für stärkere Garantien nutzen Sie manuelle Bestätigung (client.manual_ack_set(True)undclient.ack(msg.mid, msg.qos)nach dem Kafka-Delivery-Callback). - Schlüsselwahl. Verwenden Sie die Geräte-ID als Kafka-Schlüssel, damit die Messwerte jedes Geräts innerhalb einer Partition geordnet bleiben.
- Idempotenz. QoS 1 kann Duplikate zustellen. Fügen Sie eine Nachrichten-ID oder einen Zeitstempel in die Payload ein, damit nachgelagerte Konsumenten deduplizieren können.
- Skalierung. Fügen Sie Instanzen des Dienstes hinzu; das Präfix
$share/kafka-bridge/sorgt dafür, dass der Broker Nachrichten auf sie verteilt. Geben Sie jeder Instanz eine eigene Client-ID mit passenden Zugangsdaten, denn zwei Verbindungen mit derselben Client-ID würden sich gegenseitig trennen. Details finden Sie unter MQTT Shared Subscriptions.
Für einen Prototyp ohne Zugangsdaten verbinden Sie sich auf Port 1883 mit einer eindeutigen Client-ID, lassen das Präfix $share/ weg und verwenden auf dem öffentlichen MQTT-Broker ein Topic-Präfix wie connectmq/demo/<random-id>/. Behandeln Sie diese Daten als öffentlich; der öffentliche MQTT-Broker ist für Tests gedacht, nicht für Produktionsdaten.
Zwischen beiden wählen oder beide nutzen
Nutzen Sie nur MQTT, wenn Sie Echtzeit-Gerätekonnektivität, Dashboards, Alarme sowie Befehle und Steuerung brauchen und Ihr Bedarf an Historie durch eine Zeitreihendatenbank gedeckt ist, die ein Subscriber befüllt. Viele Projekte brauchen Kafka nie.
Nutzen Sie nur Kafka, wenn alle Produzenten Backend-Dienste in zuverlässigen Netzen sind und Sie dauerhafte, wiederholbare Event-Ströme zwischen Systemen brauchen.
Nutzen Sie beide, wenn Sie eine Geräteflotte und eine Datenplattform haben, die Replay, mehrere unabhängige Konsumenten mit unterschiedlichem Tempo oder Stream Processing im großen Maßstab benötigt. Halten Sie die Grenze sauber: MQTT-Topics bilden Geräte und Anlagen ab, Kafka-Topics bilden geschäftliche Event-Ströme ab.
In Industrie-4.0-Architekturen hat diese Grenze einen Namen: Der MQTT-Broker trägt den Unified Namespace (UNS), in dem die ISA-95-Ausrüstungshierarchie (Enterprise → Site → Area → Line → Cell) zur Topic-Struktur wird, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/temperatur. SPS, Gateways, MES und SCADA arbeiten in Echtzeit auf diesem UNS. Kafka übernimmt ausgewählte UNS-Daten für Langzeitanalysen, Predictive Maintenance und den Data Lake. Wie ein UNS aufgebaut ist, erklärt der Leitfaden zu Sparkplug B und Unified Namespace.
Auf der Geräteseite erspart Ihnen ein verwalteter MQTT-Broker, zwei verteilte Systeme selbst zu betreiben. Vergleichen Sie die Optionen im Leitfaden zum Cloud-MQTT-Broker, lesen Sie MQTT vs. AMQP, wenn auch Queues auf Ihrer Liste stehen, und frischen Sie die Grundlagen im MQTT-Tutorial auf.
Verbinden Sie Ihre Geräte mit ConnectMQ
Stellen Sie einen verwalteten MQTT-Broker vor Ihren Kafka-Cluster und lassen Sie jedes System das tun, was es am besten kann. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ohne Kreditkarte, verbinden Sie ein paar Geräte, richten Sie dann Ihren Consumer-Dienst darauf aus und sehen Sie zu, wie Records in Kafka ankommen.
Häufig gestellte Fragen
Kann Kafka einen MQTT-Broker ersetzen?
Nicht für Geräteflotten. Kafka fehlen schlanke Clients, Offline-Erkennung per Keep Alive, Last Will und retained Zustand, und es ist nicht für riesige Gerätezahlen in unzuverlässigen Netzen entworfen.
Kann MQTT Kafka ersetzen?
Nur, wenn Sie keine dauerhafte Historie, kein Replay und kein Stream Processing brauchen. Ein MQTT-Broker routet Nachrichten in Echtzeit und hält nur den letzten retained Wert pro Topic.
Wie bekomme ich MQTT-Daten nach Kafka?
Betreiben Sie eine Komponente, die den Broker als MQTT-Client abonniert und nach Kafka produziert, entweder Ihren eigenen Consumer-Dienst oder einen MQTT-Source-Connector für Kafka Connect. ConnectMQ hat keine integrierte Kafka-Bridge.
Sollte ich für die Bridge von MQTT zu Kafka QoS 1 oder QoS 0 verwenden?
Nutzen Sie QoS 1 für Daten, deren Verlust Sie sich nicht leisten können, und machen Sie die nachgelagerte Verarbeitung tolerant gegenüber Duplikaten. QoS 0 ist für hochfrequente Telemetrie in Ordnung, bei der eine gelegentliche Lücke akzeptabel ist.



