MQTT vs Kafka, IoT'de en sık sorulan mimari sorulardan biridir ve dürüst cevap, ikisinin sorunun farklı yarılarını çözdüğüdür. MQTT, binlerce küçük ve aralıklı bağlanan cihazdan veriyi alır; Kafka ise veri platformunuzun içinde yüksek hacimli olay akışlarını saklar, yeniden oynatır ve işler. Bu rehber ikisini karşılaştırıyor, her birinin nerede yetersiz kaldığını açıklıyor ve kontrolü sizde olan bir consumer servisiyle verileri bir MQTT broker'dan Kafka'ya taşımak için çalışan bir desen gösteriyor.
İki İş İçin İki Araç
MQTT hafif bir publish/subscribe protokolüdür. Cihazlar bir broker'a tek bir TCP bağlantısı açar, hiyerarşik topic'lere publish eder ve ihtiyaç duydukları topic'lere subscribe olur. Broker mesajları gerçek zamanlı yönlendirir, her topic için son retained değeri tutar, bağlantısı kopmuş kalıcı oturumlar için QoS 1 ve 2 mesajlarını tamponlar ve bir cihaz düştüğünde Last Will mesajını publish eder. Kısıtlı istemciler ve güvenilmez ağlar için tasarlanmıştır. Yeni başlıyorsanız bir MQTT broker'ın ne yaptığı iyi bir başlangıç noktasıdır.
Apache Kafka, dağıtık ve yalnızca sona ekleme yapılan bir commit log'dur. Producer'lar kayıtları bölümlenmiş (partitioned) topic'lere yazar, Kafka bunları yapılandırılabilir bir saklama süresi boyunca kalıcı olarak depolar ve consumer grupları kendi hızlarında okur, geçmişi yeniden işlemek için geri sarabilir. Güvenilir ağlardaki backend servislerinin sistemler arasında büyük hacimli olayları taşıması için tasarlanmıştır; ekosisteminde stream processing araçları ile veritabanlarına ve veri göllerine connector'lar bulunur.
Karışıklık ortak terminolojiden kaynaklanır. İkisinde de "topic" vardır, ikisinde de producer'lar ve consumer'lar vardır ve ikisi de mesajlaşma sistemi olarak adlandırılır. Ancak bir MQTT topic'i anında oluşturulabilen ve binlerce farklı seviye varyasyonu alabilen bir yönlendirme adresiyken, bir Kafka topic'i bilinçli olarak oluşturduğunuz, kalıcı ve bölümlenmiş bir log'dur.
Bir Bakışta MQTT vs Kafka
| Özellik | MQTT | Apache Kafka |
|---|---|---|
| Birincil amaç | Cihaz bağlantısı ve gerçek zamanlı yönlendirme | Kalıcı olay log'u ve stream processing |
| Tipik istemciler | Mikrodenetleyiciler, gateway'ler, mobil uygulamalar, tarayıcılar | Backend servisleri, stream işlemciler, connector'lar |
| Bağlantılar | Çoğu boşta duran çok sayıda bağlantı | Daha az sayıda, yüksek throughput'lu bağlantı |
| Topic'ler | Hiyerarşik, dinamik, wildcard subscription'lar | Düz adlar, önceden oluşturulmuş, bölümlenmiş |
| Depolama | Topic başına son retained değer, oturum kuyrukları | Saklama süresi boyunca tüm geçmiş |
| Yeniden oynatma | Hayır (yalnızca son retained değer) | Evet, consumer'lar herhangi bir offset'e gidebilir |
| Teslimat | Mesaj başına QoS 0, 1, 2 | Producer başına ack'ler, consumer grubu başına offset'ler |
| Sıralama | İstemci oturumu başına, topic bazında | Partition bazında |
| İstemci ayak izi | Kilobaytlar, ESP32 üzerinde çalışır | Ağır istemci kütüphaneleri, JVM veya librdkafka |
| Ağ varsayımları | Kayıplı, yüksek gecikmeli, NAT, hücresel | Güvenilir veri merkezi veya bulut ağı |
| Cihaz özellikleri | Keep alive, Last Will, retained durum | Yok |
| Tarayıcı desteği | WebSocket üzerinden MQTT | Doğrudan yok |
Cihazlar Neden Doğrudan Kafka ile Konuşmamalı?
Bir gateway üzerinde Kafka producer çalıştırmak teknik olarak mümkündür, ancak cihaz filoları için bu nadiren iyi sonuçlanır:
- İstemci ağırlığı. Kafka istemcileri bir mikrodenetleyicinin sahip olduğundan çok daha fazla bellek ve CPU gerektirir ve birden fazla broker'a kararlı bağlantılar olduğunu varsayar.
- Bağlantı modeli. Kafka, makul sayıda yoğun producer için tasarlanmıştır; her biri kararsız bağlantılar üzerinden birkaç saniyede bir ölçüm gönderen on binlerce cihaz için değil.
- Cihaz semantiği yok. Last Will, keep alive tabanlı çevrimdışı tespiti ve cihaz başına retained son bilinen değer yoktur.
- Cihazlara komutlar. Kafka consumer'ları pull yapar; NAT arkasındaki belirli bir cihaza komut push etmenin doğal bir yolu yoktur.
- Güvenlik yüzeyi. Kafka listener'larını cihazlar için internete açmak, özel bir ağın içinde durmak üzere tasarlanmış bir altyapıda cihaz başına kimlik bilgilerini ve ACL'leri yönetmek anlamına gelir.
MQTT Tek Başına Neden Bir Veri Platformu Değildir?
MQTT'de ise tam tersi eksiklikler vardır. Bir broker mesajları yönlendirir; geçmişi saklamaz. Analitik işiniz bir saat boyunca çalışmazsa, kaçırdığı ölçümler bir kalıcı oturum tarafından tutulmadıkça kaybolur ve oturum kuyrukları uzun vadeli bir depo değildir. Geçen haftanın verisini yeni bir algoritmadan geçirerek yeniden oynatamaz, broker içinde akışları birleştiremez ya da zaman pencereleri hesaplayamazsınız. Bunlar Kafka'nın ve stream processing ekosisteminin iyi olduğu işlerdir.
Desen: Kenarda MQTT, Çekirdekte Kafka
Çoğu ekibin vardığı mimari şöyle görünür:
- Cihazlar ve gateway'ler bir MQTT broker'a publish eder, örneğin
connectmq/factory1/production/line1/cnc1/telemetry. - Bir veya daha fazla consumer servisi ilgili topic filtrelerine subscribe olur.
- Bu servisler her mesajı doğrular, zenginleştirir ve anahtarlar; ardından
iot.telemetrygibi bir Kafka topic'ine produce eder. Cihaz bazında sıralamayı bir partition içinde korumak için genellikle cihaz ID'si anahtar olarak kullanılır. - Stream işlemciler, sink'ler ve analitik araçlar Kafka'dan okur.
- Komutlar ters yönde akar: bir servis Kafka'daki bir komut topic'ini tüketir ve cihazın MQTT komut topic'ine publish eder.
ConnectMQ yerleşik bir Kafka köprüsü içermez; bu nedenle ikisi arasındaki bağlantı her zaman sizin çalıştırdığınız bir bileşendir: ya aşağıda gösterildiği gibi kendi consumer servisiniz ya da broker'ınıza normal bir MQTT istemcisi olarak subscribe olacak şekilde yapılandırılmış hazır bir Kafka Connect MQTT source connector'ı. Her iki yaklaşım da broker'ı standart bir MQTT uç noktası olarak ele alır ve bu da entegrasyonu taşınabilir kılar.
MQTT'den Kafka'ya Bir Consumer Servisi Oluşturun
Aşağıdaki Python servisi ConnectMQ'ya bir shared subscription ile subscribe olur; böylece birden fazla örnek çalıştırıp yükü broker'ın aralarında paylaştırmasını sağlayabilirsiniz. Servis her mesajı confluent-kafka ile Kafka'ya produce eder. Shared subscription'lar MQTT 5 gerektirir ve ücretli Serverless plan ve üzerinde kullanılabilir.
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] # ör. 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()
Birkaç production ayrıntısı kodun kendisinden daha önemlidir:
- Geri basınç (back-pressure). Kafka kullanılamaz durumdaysa, yerel kuyruk dolduğunda
produceeninde sonundaBufferErrorfırlatır. Bloklamaya mı, QoS 0 verilerini düşürmeye mi yoksa MQTT mesajlarını onaylamayı durdurmaya mı karar verin. paho, QoS 1 mesajlarını callback döndükten sonra otomatik olarak onaylar; daha güçlü garantiler için manuel onay kullanın (client.manual_ack_set(True)ve Kafka teslim callback'inden sonraclient.ack(msg.mid, msg.qos)). - Anahtarlama. Her cihazın ölçümlerinin tek bir partition içinde sıralı kalması için Kafka anahtarı olarak cihaz ID'sini kullanın.
- Idempotence. QoS 1 tekrarlanan mesajlar iletebilir. Sonraki consumer'ların tekrarları ayıklayabilmesi için payload'a bir mesaj ID'si veya zaman damgası ekleyin.
- Ölçekleme. Servisin yeni örneklerini ekleyin;
$share/kafka-bridge/öneki broker'ın mesajları bunlar arasında dağıtmasını sağlar. Aynı client ID'ye sahip iki bağlantı birbirinin bağlantısını keseceğinden her örneğe kendi client ID'sini ve buna uygun kimlik bilgilerini verin. Ayrıntılar için MQTT shared subscription'lar yazısına bakın.
Kimlik bilgileri olmadan prototip oluşturmak için benzersiz bir client ID ile 1883 portuna bağlanın, $share/ önekini kaldırın ve herkese açık MQTT test broker'ında connectmq/demo/<random-id>/ gibi bir topic öneki kullanın. Bu verileri herkese açık kabul edin.
Aralarında Seçim Yapmak ya da İkisini Birlikte Kullanmak
Gerçek zamanlı cihaz bağlantısına, dashboard'lara, alarmlara ve komut-kontrol işlevlerine ihtiyacınız varsa ve geçmiş verisi ihtiyacınızı bir subscriber tarafından beslenen bir zaman serisi veritabanı karşılıyorsa yalnızca MQTT kullanın. Birçok proje hiçbir zaman Kafka'ya ihtiyaç duymaz.
Tüm producer'lar güvenilir ağlardaki backend servisleriyse ve sistemler arasında kalıcı, yeniden oynatılabilir olay akışlarına ihtiyacınız varsa yalnızca Kafka kullanın.
Bir cihaz filonuz ve yeniden oynatma, farklı hızlarda çalışan birden fazla bağımsız consumer ya da büyük ölçekte stream processing gerektiren bir veri platformunuz varsa ikisini birlikte kullanın. Sınırı net tutun: MQTT topic'leri cihazları ve varlıkları, Kafka topic'leri ise iş olayı akışlarını modeller.
Cihaz tarafında barındırılan bir MQTT broker, iki dağıtık sistemi kendiniz işletmekten sizi kurtarır. Seçenekleri bulut MQTT broker rehberinde karşılaştırın, listenizde kuyruklar da varsa MQTT vs AMQP yazısını okuyun ve temel bilgilerinizi MQTT eğitimiyle tazeleyin.
Cihazlarınızı ConnectMQ'ya Bağlayın
Kafka cluster'ınızın önüne yönetilen bir broker koyun ve her sistemin en iyi yaptığı işi yapmasına izin verin. app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun, birkaç cihaz bağlayın, ardından consumer servisinizi ona yönlendirin ve kayıtların Kafka'ya akışını izleyin.
Sık Sorulan Sorular
Kafka bir MQTT broker'ın yerini alabilir mi?
Cihaz filoları için hayır. Kafka'da hafif istemciler, keep alive tabanlı çevrimdışı tespiti, Last Will ve retained durum yoktur; ayrıca güvenilmez ağlardaki çok sayıda cihaz için tasarlanmamıştır.
MQTT, Kafka'nın yerini alabilir mi?
Yalnızca kalıcı geçmişe, yeniden oynatmaya veya stream processing'e ihtiyacınız yoksa. Bir MQTT broker mesajları gerçek zamanlı yönlendirir ve her topic için yalnızca son retained değeri tutar.
MQTT verilerini Kafka'ya nasıl aktarırım?
Broker'a bir MQTT istemcisi olarak subscribe olan ve Kafka'ya produce eden bir bileşen çalıştırın; bu ya kendi consumer servisiniz ya da bir Kafka Connect MQTT source connector'ı olabilir. ConnectMQ'da yerleşik bir Kafka köprüsü yoktur.
MQTT'den Kafka'ya köprü için QoS 1 mi yoksa QoS 0 mı kullanmalıyım?
Kaybetmeyi göze alamayacağınız veriler için QoS 1 kullanın ve sonraki işlemleri tekrarlara dayanıklı hale getirin. Ara sıra oluşan boşlukların kabul edilebilir olduğu yüksek frekanslı telemetri için QoS 0 yeterlidir.



