MQTT vs Kafka est l'une des questions d'architecture les plus courantes dans l'IoT, et la réponse honnête est qu'ils résolvent chacun une moitié différente du problème. MQTT récupère les données de milliers de petits appareils connectés par intermittence ; Kafka stocke, rejoue et traite des flux d'événements à fort volume au sein de votre plateforme de données. Ce guide compare les deux, explique où chacun atteint ses limites et présente un schéma fonctionnel pour faire passer les données d'un broker MQTT vers Kafka à l'aide d'un service consommateur que vous maîtrisez.
Deux outils pour deux missions
MQTT est un protocole publish/subscribe léger. Les appareils ouvrent une connexion TCP vers un broker, publient sur des topics hiérarchiques et s'abonnent aux topics dont ils ont besoin. Le broker achemine les messages en temps réel, conserve la dernière valeur retenue de chaque topic, met en mémoire tampon les messages QoS 1 et 2 pour les sessions persistantes déconnectées et publie un Last Will lorsqu'un appareil décroche. Il est conçu pour des clients contraints et des réseaux peu fiables. Si vous le découvrez, le rôle d'un broker MQTT est un bon point de départ.
Apache Kafka est un journal de commits distribué, en ajout seul. Les producteurs écrivent des enregistrements dans des topics partitionnés, Kafka les stocke durablement pendant une période de rétention configurable, et les groupes de consommateurs les lisent à leur propre rythme et peuvent revenir en arrière pour retraiter l'historique. Il est conçu pour des services backend sur des réseaux fiables qui font circuler de gros volumes d'événements entre systèmes, avec un écosystème d'outils de traitement de flux et de connecteurs vers les bases de données et les data lakes.
La confusion vient du vocabulaire commun. Les deux ont des « topics », des producteurs et des consommateurs, et les deux sont qualifiés de systèmes de messagerie. Mais un topic MQTT est une adresse de routage qui peut être créée à la volée avec des milliers de variantes de niveaux, alors qu'un topic Kafka est un journal durable et partitionné que vous provisionnez délibérément.
MQTT vs Kafka en un coup d'œil
| Aspect | MQTT | Apache Kafka |
|---|---|---|
| Finalité principale | Connectivité des appareils et routage en temps réel | Journal d'événements durable et traitement de flux |
| Clients typiques | Microcontrôleurs, passerelles, applications mobiles, navigateurs | Services backend, moteurs de traitement de flux, connecteurs |
| Connexions | Très nombreuses, majoritairement inactives | Moins nombreuses, à haut débit |
| Topics | Hiérarchiques, dynamiques, abonnements avec wildcards | Noms plats, provisionnés, partitionnés |
| Stockage | Dernière valeur retenue par topic, files de session | Historique complet sur la période de rétention |
| Relecture (replay) | Non (seulement la dernière valeur retenue) | Oui, les consommateurs peuvent se positionner sur n'importe quel offset |
| Livraison | QoS 0, 1, 2 par message | Acks par producteur, offsets par groupe de consommateurs |
| Ordre | Par topic et par session client | Par partition |
| Empreinte client | Quelques kilo-octets, tourne sur un ESP32 | Bibliothèques clientes lourdes, JVM ou librdkafka |
| Hypothèses réseau | Pertes, forte latence, NAT, cellulaire | Réseau fiable de datacenter ou de cloud |
| Fonctions dédiées aux appareils | Keep alive, Last Will, état retenu | Aucune |
| Prise en charge des navigateurs | MQTT sur WebSocket | Pas directement |
Pourquoi les appareils ne devraient pas parler directement à Kafka
Il est techniquement possible d'exécuter un producteur Kafka sur une passerelle, mais cela se termine rarement bien pour les flottes d'appareils :
- Poids du client. Les clients Kafka ont besoin de bien plus de mémoire et de CPU qu'un microcontrôleur n'en possède, et ils supposent des connexions stables vers plusieurs brokers.
- Modèle de connexion. Kafka est conçu pour un nombre modeste de producteurs très actifs, pas pour des dizaines de milliers d'appareils envoyant chacun une mesure toutes les quelques secondes sur des liaisons instables.
- Aucune sémantique propre aux appareils. Pas de Last Will, pas de détection de déconnexion basée sur le keep-alive, pas de dernière valeur connue retenue par appareil.
- Commandes vers les appareils. Les consommateurs Kafka tirent les données (pull) ; il n'existe aucun moyen naturel de pousser une commande vers un appareil précis situé derrière un NAT.
- Surface de sécurité. Exposer des listeners Kafka sur Internet pour les appareils revient à gérer des identifiants et des ACL par appareil sur une infrastructure conçue pour rester au sein d'un réseau privé.
Pourquoi MQTT seul n'est pas une plateforme de données
MQTT présente les lacunes inverses. Un broker achemine les messages ; il ne conserve pas d'historique. Si votre traitement analytique est arrêté pendant une heure, les mesures manquées sont perdues, sauf si une session persistante les a conservées, et les files de session ne sont pas un stockage à long terme. Vous ne pouvez pas rejouer les données de la semaine dernière dans un nouvel algorithme, ni joindre des flux ou calculer des fenêtres au sein du broker. C'est précisément le travail dans lequel Kafka et son écosystème de traitement de flux excellent.
Le schéma : MQTT en périphérie, Kafka au cœur
L'architecture vers laquelle convergent la plupart des équipes ressemble à ceci :
- Les appareils et passerelles publient vers un broker MQTT, par exemple sur
connectmq/factory1/production/line1/cnc1/telemetry. - Un ou plusieurs services consommateurs s'abonnent aux topic filters pertinents.
- Ces services valident, enrichissent et attribuent une clé à chaque message, puis le produisent dans un topic Kafka comme
iot.telemetry, généralement avec l'ID de l'appareil comme clé afin de préserver l'ordre par appareil au sein d'une partition. - Les moteurs de traitement de flux, les sinks et les outils d'analyse lisent depuis Kafka.
- Les commandes circulent en sens inverse : un service consomme un topic Kafka de commandes et publie sur le topic de commande MQTT de l'appareil.
ConnectMQ n'inclut pas de passerelle Kafka intégrée : le lien entre les deux est donc toujours un composant que vous exécutez, soit votre propre service consommateur, comme ci-dessous, soit un connecteur source MQTT prêt à l'emploi pour Kafka Connect, configuré pour s'abonner à votre broker comme un client MQTT ordinaire. Les deux approches traitent le broker comme un point d'accès MQTT standard, ce qui rend l'intégration portable.
Construire un service consommateur MQTT vers Kafka
Le service Python suivant s'abonne à ConnectMQ avec un abonnement partagé, ce qui vous permet d'exécuter plusieurs instances et de laisser le broker répartir la charge entre elles, et produit chaque message dans Kafka avec confluent-kafka. Les abonnements partagés nécessitent MQTT 5 et sont disponibles à partir du plan Serverless payant.
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] # par ex. 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()
Quelques détails de production comptent davantage que le code lui-même :
- Contre-pression (back-pressure). Si Kafka est indisponible,
producefinira par leverBufferErrorune fois la file locale pleine. Décidez s'il faut bloquer, abandonner les données QoS 0 ou cesser d'acquitter les messages MQTT. paho acquitte automatiquement les messages QoS 1 au retour du callback ; pour des garanties plus fortes, utilisez donc l'acquittement manuel (client.manual_ack_set(True)etclient.ack(msg.mid, msg.qos)après le callback de livraison Kafka). - Clés. Utilisez l'ID de l'appareil comme clé Kafka pour que les mesures de chaque appareil restent ordonnées au sein d'une même partition.
- Idempotence. La QoS 1 peut livrer des doublons. Incluez un identifiant de message ou un horodatage dans le payload afin que les consommateurs en aval puissent dédupliquer.
- Montée en charge. Ajoutez des instances du service ; le préfixe
$share/kafka-bridge/amène le broker à répartir les messages entre elles. Donnez à chaque instance son propre client ID et les identifiants correspondants, car deux connexions avec le même client ID se déconnecteraient mutuellement. Consultez les abonnements partagés MQTT pour les détails.
Pour prototyper sans identifiants, connectez-vous au port 1883 avec un client ID unique, retirez le préfixe $share/ et utilisez un préfixe de topic comme connectmq/demo/<random-id>/ sur le serveur MQTT public gratuit. Considérez ces données comme publiques : ce serveur est réservé aux tests.
Choisir entre les deux, ou utiliser les deux
Utilisez MQTT seul lorsque vous avez besoin de connectivité des appareils en temps réel, de tableaux de bord, d'alertes et de contrôle-commande, et que vos besoins d'historique sont couverts par une base de données de séries temporelles alimentée par un abonné. De nombreux projets n'ont jamais besoin de Kafka.
Utilisez Kafka seul lorsque tous les producteurs sont des services backend sur des réseaux fiables et que vous avez besoin de flux d'événements durables et rejouables entre systèmes.
Utilisez les deux lorsque vous avez une flotte d'appareils et une plateforme de données qui exige la relecture, plusieurs consommateurs indépendants travaillant à des vitesses différentes ou du traitement de flux à grande échelle. Gardez une frontière nette : les topics MQTT modélisent les appareils et les actifs, les topics Kafka modélisent les flux d'événements métier.
Côté appareils, un broker MQTT managé vous évite d'exploiter vous-même deux systèmes distribués. Comparez les options dans le guide du broker MQTT cloud, lisez MQTT vs AMQP si les files figurent aussi sur votre liste, et révisez les fondamentaux dans le tutoriel MQTT.
Connectez vos appareils à ConnectMQ
Placez un broker MQTT managé devant votre cluster Kafka et laissez chaque système faire ce qu'il fait de mieux. Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire, connectez quelques appareils, puis pointez votre service consommateur vers lui et regardez les enregistrements arriver dans Kafka.
Questions fréquentes
Kafka peut-il remplacer un broker MQTT ?
Pas pour les flottes d'appareils. Kafka ne dispose ni de clients légers, ni de détection de déconnexion basée sur le keep-alive, ni de Last Will, ni d'état retenu, et il n'est pas conçu pour un très grand nombre d'appareils sur des réseaux peu fiables.
MQTT peut-il remplacer Kafka ?
Seulement si vous n'avez besoin ni d'historique durable, ni de relecture, ni de traitement de flux. Un broker MQTT achemine les messages en temps réel et ne conserve que la dernière valeur retenue de chaque topic.
Comment faire entrer des données MQTT dans Kafka ?
Exécutez un composant qui s'abonne au broker en tant que client MQTT et produit dans Kafka : soit votre propre service consommateur, soit un connecteur source MQTT pour Kafka Connect. ConnectMQ ne dispose pas de passerelle Kafka intégrée.
Faut-il utiliser la QoS 1 ou la QoS 0 pour la passerelle MQTT vers Kafka ?
Utilisez la QoS 1 pour les données que vous ne pouvez pas vous permettre de perdre, et rendez le traitement en aval tolérant aux doublons. La QoS 0 convient à la télémétrie à haute fréquence pour laquelle une lacune occasionnelle est acceptable.



