Wer einen MQTT-Broker skalieren will, muss zuerst wissen, welche Art von Last tatsächlich wächst: Verbindungen, eingehende Nachrichten oder ausgehender Fan-out. Dieser Leitfaden erklärt jede Dimension, vergleicht vertikale und horizontale Skalierung, rechnet die Fan-out-Mathematik durch, die Sie für die Dimensionierung brauchen, und zeigt die clientseitigen Gewohnheiten, die oft mehr zählen als der Broker selbst.
Die drei Dimensionen der MQTT-Last
Ein MQTT-Broker verrichtet drei verschiedene Arten von Arbeit, und sie skalieren unabhängig voneinander.
Verbindungen. Jeder verbundene Client hält einen TCP-Socket, bei Verschlüsselung eine TLS-Sitzung, ein Sitzungszustandsobjekt und Keepalive-Timer. Verbindungslast betrifft vor allem Arbeitsspeicher und Dateideskriptoren und wächst mit der Flottengröße, selbst wenn die Geräte ruhig sind.
Eingehende Nachrichten. Jedes PUBLISH eines Clients muss geparst, autorisiert, mit den Subscriptions abgeglichen und bei QoS 1 oder 2 bestätigt werden. Die eingehende Last wächst mit der Flottengröße multipliziert mit der Publish-Frequenz.
Ausgehender Fan-out. Für jede eingehende Nachricht stellt der Broker jedem passenden Subscriber eine Kopie zu. Ein Sensormesswert, den ein Dashboard, ein Datenbank-Writer und ein Alarmdienst konsumieren, wird zu drei ausgehenden Nachrichten. Fan-out ist die Dimension, die Teams am häufigsten vergessen, und oft die größte.
Ein vierter, leiserer Faktor ist der Sitzungszustand: Persistente Sitzungen mit gepufferten QoS-1-Nachrichten für Offline-Clients belegen Speicher, bis diese Clients zurückkehren oder die Sitzung abläuft.
Fan-out-Mathematik: die tatsächliche Broker-Last abschätzen
Um über Last nachzudenken, brauchen Sie keinen Benchmark, sondern Arithmetik. Die Grundformeln lauten:
- Eingangsrate = Geräte x Nachrichten pro Gerät und Sekunde
- Ausgangsrate = Summe über alle Topics von (Eingangsrate auf diesem Topic x passende Subscriber)
- Die gesamte Broker-Arbeit entspricht grob Eingang plus Ausgang, mit Zusatzkosten für QoS-1- und QoS-2-Bestätigungen sowie für TLS
Hier ist ein kleiner Rechner, den Sie an Ihre eigene Flotte anpassen können. Die Zahlen darin sind ein Beispiel, keine Messung.
# fanout.py - grobe Abschätzung der MQTT-Last für die Kapazitätsplanung
fleet = [
# (name, devices, msgs_per_device_per_min, subscribers_per_message, avg_payload_bytes)
("env sensors", 400, 2, 2, 180),
("machines", 60, 60, 3, 600),
("status", 460, 0.1, 1, 20),
]
total_in = total_out = total_bytes = 0.0
for name, devices, per_min, subs, size in fleet:
inbound = devices * per_min / 60
outbound = inbound * subs
total_in += inbound
total_out += outbound
total_bytes += (inbound + outbound) * size
print(f"{name:12s} in={inbound:7.1f}/s out={outbound:7.1f}/s")
print(f"\nTOTAL inbound {total_in:8.1f} msg/s")
print(f"TOTAL outbound {total_out:8.1f} msg/s")
print(f"Approx traffic {total_bytes/1024:8.1f} KB/s (payload only, no protocol/TLS overhead)")
Führen Sie ihn mit python fanout.py aus. Meist springen zwei Erkenntnisse ins Auge. Erstens können eine Handvoll gesprächiger Maschinen schwerer wiegen als Hunderte langsamer Sensoren. Zweitens kann ein zusätzlicher Subscriber auf einem Topic mit hohem Volumen, etwa ein zweiter Analysedienst, die ausgehende Last stärker erhöhen als Hunderte zusätzlicher Geräte. Eine ausführlichere Anleitung finden Sie unter MQTT-Nachrichten pro Sekunde abschätzen.
Vertikale vs. horizontale Skalierung
Es gibt zwei grundlegende Wege, einem Broker mehr Kapazität zu geben.
| Vertikale Skalierung | Horizontale Skalierung | |
|---|---|---|
| Wie | Größere Maschine: mehr CPU, Speicher, Netzwerk | Mehr Broker-Knoten, die zusammenarbeiten |
| Komplexität | Gering; Konfiguration bleibt weitgehend gleich | Höher; Knoten müssen Routing und Sitzungszustand teilen |
| Fehlerdomäne | Ein Knoten | Mehrere Knoten, je nach Design |
| Typische Grenze | Größte verfügbare Maschine | Koordinationsaufwand zwischen den Knoten |
| Geeignet für | Die meisten kleinen und mittleren Flotten | Sehr große Flotten oder strenge Redundanzziele |
Vertikale Skalierung wird unterschätzt. Ein einzelner, gut abgestimmter Broker-Prozess auf angemessener Hardware bewältigt eine große Menge Traffic, und die betriebliche Einfachheit ist wertvoll. Zum Tuning gehören meist höhere Limits für Dateideskriptoren, ausreichend Speicher für Sitzungen und In-flight-Nachrichten sowie das Auslagern oder Optimieren von TLS.
Horizontale Skalierung bedeutet mehrere Broker-Knoten hinter einem Load Balancer. Schwierig ist nicht das Hinzufügen von Knoten, sondern sie konsistent zu halten: Eine auf Knoten A publizierte Nachricht muss einen Subscriber erreichen, der mit Knoten B verbunden ist, und ein Client, der sich mit einem anderen Knoten neu verbindet, erwartet, seine Sitzung vorzufinden. Verschiedene Broker-Produkte lösen das auf unterschiedliche Weise, mit unterschiedlichen Abwägungen bei Latenz und Konsistenz.
Ein drittes Muster ist die Partitionierung: separate, unabhängige Broker für einzelne Standorte, Mandanten oder Produktlinien. Sie vermeidet die Koordination zwischen Knoten vollständig, um den Preis, dass es keinen globalen Topic-Raum gibt. Für viele Installationen mit mehreren Standorten und Kunden ist Partitionierung der einfachste Weg zu wachsen. In der Fertigung bietet sich dafür die Site-Ebene eines Unified Namespace (UNS) nach ISA-95 an: Jedes Werk erhält einen eigenen Broker für seinen Teilbaum, etwa acme/werk-muenchen/..., und nur ausgewählte Kennzahlen wie OEE oder Energieverbrauch werden an eine zentrale Ebene weitergereicht. Wie die ISA-95-Ebenen auf den UNS abgebildet werden, zeigt der Beitrag Sparkplug B und Unified Namespace.
Die Consumer-Seite mit Shared Subscriptions skalieren
Backend-Consumer sind oft der erste Engpass. Ein einzelner Python-Dienst, der acme/# abonniert hat, muss jede Nachricht der Flotte verarbeiten. Fällt er zurück, stauen sich Nachrichten auf dem Broker und der Speicherbedarf wächst.
MQTT-5-Shared-Subscriptions lösen das, indem sich mehrere Consumer-Instanzen eine Subscription teilen. Jede Nachricht geht an ein Mitglied der Gruppe statt an alle. Shared Subscriptions sind im ConnectMQ-Plan Serverless (Paid) verfügbar.
import os
import paho.mqtt.client as mqtt
GROUP = "writers"
FILTER = "acme/+/+/+/+/telemetry"
def on_connect(client, userdata, flags, reason_code, properties):
print("connected:", reason_code)
client.subscribe(f"$share/{GROUP}/{FILTER}", qos=1)
def on_message(client, userdata, msg):
# Hier in Ihre Datenbank, Queue oder Datei schreiben.
print(os.getpid(), msg.topic, len(msg.payload), "bytes")
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()
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 8883)
client.loop_forever()
Der Filter acme/+/+/+/+/telemetry passt zu einer UNS-Topic-Struktur nach ISA-95 mit den Ebenen Enterprise, Site, Area, Line und Cell, also etwa acme/werk-stuttgart/montage/linie-1/zelle-3/telemetry. Betreiben Sie eine Kopie pro Consumer-Instanz, jeweils mit eigenen Zugangsdaten und eigener Client ID. Eine weitere Instanz verteilt die Last zusätzlich, ohne dass Sie die Geräte anfassen müssen.
Client-Gewohnheiten, die skalieren
Viele Skalierungsprobleme sind in Wahrheit Client-Probleme. Diese Gewohnheiten helfen auf jedem Broker:
- Bei Änderung publizieren, nicht nach Timer. Report-by-Exception senkt die eingehende Last bei sich langsam ändernden Werten drastisch.
- Messwerte bündeln. Senden Sie zehn Messwerte in einer Nachricht statt in zehn Nachrichten.
- QoS bewusst einsetzen. QoS 0 für hochfrequente Telemetrie, bei der der nächste Messwert den letzten ersetzt; QoS 1 für Ereignisse und Befehle; QoS 2 nur dort, wo Duplikate inakzeptabel sind. Siehe MQTT-QoS-Level erklärt.
- Eng abonnieren. Ein Dashboard, das einen Standort zeigt, sollte nicht
#abonnieren. - Sinnvolle Keepalives setzen. Sehr kurze Keepalives vervielfachen den PINGREQ-Traffic über eine große Flotte.
- Jitter bei Reconnects und periodischen Publishes ergänzen. Tausende Geräte, die in exakt derselben Sekunde publizieren, erzeugen unnötige Lastspitzen.
- Ablaufen lassen, was Sie nicht brauchen. Session Expiry und Message Expiry verhindern, dass der Broker Zustand für Clients hält, die nie zurückkehren.
- Topic-Aliase für lange Topics auf eingeschränkten Verbindungen nutzen. MQTT-5-Topic-Aliase ersetzen wiederholte lange Topic-Strings durch eine kurze Ganzzahl.
Wann ein größerer Plan fällig ist
Bei einem verwalteten MQTT-Broker ist Skalierung meist eine Planentscheidung. Bei ConnectMQ sieht die Leiter so aus:
- Serverless (Free): bis zu 25 Verbindungen, QoS bis 1, Nachrichten bis 256 KB. Prototypen und kleine Pilotprojekte.
- Serverless (Paid): bis zu 1.000 Verbindungen, QoS 2, Nachrichten bis 1 MB, Shared Subscriptions. Wachsende Flotten auf einem geteilten Cluster.
- Dedicated: ein isolierter Cluster, damit Ihr Workload keine Ressourcen mit anderen Mandanten teilt.
- BYOC: ein Broker, der in Ihrem eigenen Cloud-Konto läuft und von ConnectMQ verwaltet wird, nützlich, wenn Sie die Infrastruktur selbst wählen und kontrollieren möchten.
- Self Managed Enterprise: für Organisationen, die den Broker selbst betreiben müssen.
Signale für einen Aufstieg sind etwa, dass Sie sich der Verbindungsobergrenze nähern, Shared Subscriptions für Backend-Consumer brauchen oder Isolation vom Traffic anderer Mandanten wünschen. Sprechen Sie mit dem Team über erwartete Verbindungen und Nachrichtenraten, damit eine Dedicated- oder Enterprise-Bereitstellung passend zu Ihrem Workload dimensioniert wird. Wenn Sie die Modelle allgemein vergleichen, behandelt der Leitfaden zum Cloud-MQTT-Broker jedes davon, und Hochverfügbarkeit von MQTT-Brokern erklärt die Redundanzfragen, die Sie neben der Kapazität stellen sollten.
Skalierungsfallen, die Sie vermeiden sollten
- Dimensionierung nach Durchschnittswerten. Planen Sie für Spitzen wie Schichtwechsel, Reconnect-Stürme und nachgesendete Rückstaus.
- Subscriber ignorieren. Zählen Sie den ausgehenden Fan-out, nicht nur die Geräte.
- Ein einziger riesiger Wildcard-Consumer. Teilen Sie ihn mit Shared Subscriptions auf, bevor er zum Engpass wird.
- Überall große Retained Messages. Jeder neue Subscriber erhält sie sofort, was sich bei breiten Wildcards summiert.
- Lasttests gegen die Produktion. Verwenden Sie für Lasttests einen separaten Broker oder Plan, damit Sie nicht an Ihre eigenen Kontingente stoßen.
Skalieren Sie Ihre MQTT-Flotte mit ConnectMQ
Mit ConnectMQ können Sie klein anfangen und die Planleiter hinaufsteigen, während Ihre Verbindungen und Ihr Fan-out wachsen, ohne Protokolle oder Topic-Design zu ändern. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ohne Kreditkarte, und führen Sie ein Upgrade durch, wenn Ihre Zahlen es verlangen. Wenn Sie vor der Planung auffrischen möchten, was ein MQTT-Broker macht, beginnen Sie dort.
Häufig gestellte Fragen
Was begrenzt die Skalierung eines MQTT-Brokers meist zuerst?
Das hängt vom Workload ab. Große, ruhige Flotten stoßen zuerst an Verbindungs- und Speicherlimits, während aktive Flotten mit mehreren Consumern pro Topic zuerst an die Grenzen des ausgehenden Fan-outs stoßen.
Ist horizontale Skalierung immer besser als vertikale?
Nein. Vertikale Skalierung ist einfacher und reicht für viele Installationen aus. Horizontale Skalierung bringt Koordinationsaufwand mit sich und lohnt sich, wenn ein einzelner Knoten die Kapazitäts- oder Redundanzziele nicht erfüllen kann.
Wie helfen Shared Subscriptions beim Skalieren?
Sie erlauben mehreren Consumer-Instanzen, sich eine Subscription zu teilen, sodass jede Nachricht einmal von einem Mitglied der Gruppe verarbeitet wird. Das beseitigt den Engpass eines einzelnen Consumers, ohne die Geräte zu ändern.
Wann sollte ich von Serverless zu Dedicated wechseln?
Erwägen Sie Dedicated, wenn Sie Isolation von anderen Mandanten brauchen oder eine Last erwarten, die über das hinausgeht, was die geteilten Serverless-Pläne bieten. Teilen Sie Ihre erwarteten Verbindungen und Nachrichtenraten mit, damit die Bereitstellung richtig dimensioniert wird.



