MQTT Temelleri

MQTT Bant Genişliği Kullanımı: Mesaj Başına Ek Yükü Hesaplama

Bir MQTT mesajı gerçekte kaç bayta mal olur? Her QoS seviyesinde connect, keep alive ve publish ek yükünü hesaplayın, TCP ve TLS'i ekleyin ve hücresel IoT cihazları için aylık veri tahmini oluşturun.

mqtt bant genişliği kullanımını göstermek için tek bir mesajı payload, MQTT, TCP ve TLS baytlarına ayıran yığılmış çubuk grafik
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Her baytın nereden geldiğini bildiğinizde MQTT bant genişliği kullanımını tahmin etmek kolaydır: MQTT paketinin kendisi, onu taşıyan TCP/IP başlıkları, etrafındaki TLS şifrelemesi ve connect ile keep alive işlemlerinin arka plan trafiği. Bu rehber, gerçekçi bir telemetri mesajı için her katmanı QoS 0, 1 ve 2'de hesaplıyor, ardından bu sayıları cihazlarınız için hücresel bir plan seçerken kullanabileceğiniz aylık bir veri tahminine dönüştürüyor.

MQTT Neden Hafiftir ve Baytlar Yine de Nereye Gider?

MQTT'nin sabit başlığı iki bayt kadar küçüktür, HTTP'deki gibi metin başlıkları yoktur ve tek bir uzun ömürlü bağlantı, her istek için yapılan el sıkışmanın yerini alır. Bu da mesaj başına protokol ek yükünü çok küçük kılar. Ancak ölçülen (metered) bir bağlantıda MQTT baytları için değil IP baytları için ödeme yaparsınız ve küçük payload'larda alt katmanlar baskın gelir. Faydalı bir zihinsel modelin dört katmanı vardır:

Katman Mesaj başına maliyet Notlar
Payload Verileriniz Telemetri için genellikle 20 ila 200 bayt JSON
MQTT 2 ila 6 bayt + topic adı Topic uzunluğu çoğu zaman en büyük MQTT maliyetidir
TLS Kayıt başına yaklaşık 22 ila 29 bayt TLS sürümüne ve şifreleme takımına bağlıdır
TCP/IP Segment başına 40 bayt (IPv4, seçeneksiz) TCP zaman damgalarıyla çoğu zaman 52; IPv6 ile 60

Bunlara ek olarak mesaj başına olmayan iki arka plan maliyeti vardır: bağlantı kurulumu (TCP, TLS el sıkışması, CONNECT) ve boşta kalırken gönderilen keep alive ping'leri. Her ikisi de aşağıda ele alınıyor. MQTT katmanının bayt düzeyindeki yapısı için MQTT paket yapısı rehberine bakın.

QoS'a Göre Mesaj Başına MQTT Ek Yükü

Tipik bir örnek alalım: MQTT 3.1.1, plant1/line2/pump3/telemetry topic'i (28 karakter) ve {"t":1760601600,"flow":12.4,"p":3.1,"temp":41.7} gibi 48 baytlık bir JSON payload'ı.

QoS 0'da PUBLISH paketi şöyledir:

  • Sabit başlık: 2 bayt (tür ve bayraklar, bir bayt remaining length)
  • Topic: 2 baytlık uzunluk öneki + 28 bayt = 30 bayt
  • Payload: 48 bayt
  • Toplam: 80 bayt

QoS 1 ve 2'de PUBLISH'e 2 baytlık bir paket kimliği eklenir ve her biri 4 bayt olan onay paketleri devreye girer:

QoS Hattaki paketler MQTT baytı Payload'a göre ek yük
0 PUBLISH (80) 80 32 bayt
1 PUBLISH (82) + PUBACK (4) 86 38 bayt
2 PUBLISH (82) + PUBREC + PUBREL + PUBCOMP (her biri 4) 94 46 bayt

MQTT 5'te PUBLISH'teki boş özellik uzunluğu için bir bayt ekleyin; özellik içermeyen başarılı onaylar 4 baytta kalır. Dolayısıyla MQTT katmanında QoS seçimi maliyeti yalnızca biraz değiştirir. Asıl fark taşıma katmanında ortaya çıkar, çünkü her ek paket genellikle ek bir TCP segmenti anlamına gelir. MQTT QoS seviyeleri rehberi, ek teslimat garantilerinin ne zaman buna değdiğini açıklıyor.

Topic Adı Çoğu Zaman En Büyük MQTT Maliyetidir

Yukarıdaki örnekte QoS 0 ek yükünün 32 baytının 30'u topic'tir. Derin ISA-95 tarzı topic'ler kolayca 50 karakteri aşabilir. İki çözüm vardır: cihaz tarafındaki topic'leri kısa tutun ya da ilk publish'ten sonra topic'i 2 baytlık bir sayıyla değiştiren MQTT 5 topic alias'larını kullanın. MQTT topic alias rehberi tasarrufu ayrıntılı olarak gösteriyor.

TCP/IP ve TLS'i Eklemek

Tek başına gönderilen her MQTT paketi, en az 40 baytlık IPv4 ve TCP başlıklarına sahip bir TCP segmentinde taşınır. Alıcı, verileri TCP ACK'leriyle onaylar; bunlar da ters yönde akan verilere eklenemedikleri sürece 40 baytlık segmentlerdir. Gecikmeli ACK davranışı işletim sistemine ve ağ yığınına göre değişir, bu yüzden ACK maliyetlerini yaklaşık değerler olarak kabul edin.

TLS, her yazma işlemini bir kayıt (record) içine sarar. TLS 1.3 ve AES-GCM şifrelemesiyle her kayıt 5 baytlık başlık, 1 baytlık iç içerik türü ve 16 baytlık kimlik doğrulama etiketi ekler: toplam 22 bayt. AES-GCM ile TLS 1.2 ise 8 baytlık açık nonce nedeniyle 29 bayt ekler.

Hepsini bir telemetri mesajı için bir araya getirdiğimizde (TCP seçenekleri olmadan IPv4, TLS 1.3, veri segmenti başına bir saf TCP ACK sayarak):

QoS Düz TCP (port 1883) TLS 1.3 (port 8883)
0 80 + 40 + 40 ACK = 160 bayt 102 + 40 + 40 ACK = 182 bayt
1 122 + 44 + 40 ACK = 206 bayt 144 + 66 + 40 ACK = 250 bayt
2 122 + 3 x 44 + 2 ACK, yaklaşık 335 bayt 144 + 3 x 66 + 2 ACK, yaklaşık 420 bayt

48 baytlık bir payload için hattaki maliyet, verinin kabaca dört ila sekiz katıdır. Payload'lar büyüdükçe bu oran küçülür: 1 KB'lık bir payload neredeyse aynı mutlak ek yüke sahiptir ve bu ek yük küçük bir orana dönüşür. Bu nedenle ölçümleri gruplamak, örneğin on mesaj yerine on örnek içeren tek bir mesaj göndermek, en etkili bant genişliği optimizasyonudur.

Gerçek kurulumlarda TLS isteğe bağlı değildir ve tablonun gösterdiği gibi mesaj başına maliyeti makuldür. Daha büyük maliyeti el sıkışmasıdır.

Bağlantı Kurulum Maliyetleri

Her yeni bağlantı şunlar için ödeme yapar:

  1. TCP el sıkışması: üç segment, kabaca 120 ila 180 bayt.
  2. TLS el sıkışması: genellikle birkaç kilobayt, çoğunlukla sunucunun sertifika zinciri. Kütüphanenizin desteklediği durumlarda TLS 1.3 oturum sürdürme (session resumption) bunu önemli ölçüde azaltır.
  3. CONNECT ve CONNACK: 20 karakterlik client ID, kullanıcı adı ve parola içeren bir CONNECT yaklaşık 80 bayttır; CONNACK ise MQTT 3.1.1'de 4 bayttır.
  4. Kalıcı oturum kullanılmıyorsa her abonelik için SUBSCRIBE ve SUBACK.

Yani tek bir yeniden bağlanma, onlarca telemetri mesajı kadar maliyetli olabilir. Her dakika bağlanan, bir kez publish eden ve bağlantıyı kesen cihazlar verilerinin çoğunu el sıkışmalarına harcar. Cihaz uzun süreler boyunca uykuya geçmiyorsa bağlantıyı açık tutun ve her yeniden bağlanmadan sonra tekrar abone olmak zorunda kalmamak için kalıcı oturum kullanın. Kalıcı oturum rehberi bunun nasıl yapılacağını açıklıyor.

Keep Alive Maliyetleri

Bir istemcinin keep alive aralığı boyunca gönderecek bir şeyi olmadığında PINGREQ (2 bayt) gönderir ve broker PINGRESP (2 bayt) ile yanıt verir. TLS 1.3 ve TCP/IP ile bir ping değişimi yaklaşık 64 + 64 bayt artı bir ACK'tir: kabaca 170 bayt.

Keep alive Boştayken günlük ping sayısı Yaklaşık günlük veri
30 sn 2.880 yaklaşık 485 KB
60 sn 1.440 yaklaşık 240 KB
300 sn 288 yaklaşık 48 KB
900 sn 96 yaklaşık 16 KB

Ping'ler yalnızca bağlantı başka bir şekilde boştayken gönderilir; bu nedenle 60 saniyelik keep alive ile her 30 saniyede bir publish yapan bir cihaz hiç ping göndermez. Daha uzun aralıklar veri tasarrufu sağlar, ancak hücresel ağlarda boştaki bağlantıları düşüren ve maliyetli bir yeniden bağlanmaya zorlayan NAT zaman aşımları riskini taşır. Bu değeri MQTT keep alive aralığı yazısındaki önerilerle ayarlayın.

Hücresel Bir Cihaz için Aylık Veri Tahmini

Bu Python hesaplayıcısı tüm parçaları bir araya getirir. Girdileri cihazınıza göre ayarlayın:

def mqtt_monthly_bytes(
    payload=48, topic_len=28, qos=1, msgs_per_day=1440,
    tls=True, reconnects_per_day=2, handshake_bytes=5000,
    keepalive_s=120, idle_seconds_per_day=0,
):
    ip_tcp = 40
    tls_rec = 22 if tls else 0
    publish = 2 + 2 + topic_len + payload + (2 if qos else 0)

    def seg(mqtt_bytes):
        return mqtt_bytes + tls_rec + ip_tcp

    if qos == 0:
        per_msg = seg(publish) + ip_tcp
    elif qos == 1:
        per_msg = seg(publish) + seg(4) + ip_tcp
    else:
        per_msg = seg(publish) + 3 * seg(4) + 2 * ip_tcp

    pings = idle_seconds_per_day / keepalive_s if keepalive_s else 0
    ping_bytes = pings * (2 * seg(2) + ip_tcp)
    connect_bytes = reconnects_per_day * (handshake_bytes if tls else 300)

    per_day = msgs_per_day * per_msg + ping_bytes + connect_bytes
    return per_day * 30

for qos in (0, 1, 2):
    mb = mqtt_monthly_bytes(qos=qos) / 1_000_000
    print(f"QoS {qos}: {mb:.1f} MB per month")

TLS üzerinden QoS 1 ile dakikada bir mesajda sonuç, cihaz başına ayda yaklaşık 11 MB'tır ve bunun yalnızca küçük bir kısmı varsayılan iki yeniden bağlanmadan gelir. msgs_per_day değerini 144'e (on dakikada bir) değiştirip 300 saniyelik keep alive ve boşta geçen süreyi eklediğinizde toplam keskin biçimde düşer. Bunlar ölçüm değil, hesaplanmış tahminlerdir; bir test SIM kartında gerçek kullanımı kontrol ederek veya bir gün boyunca tcpdump ile trafiği yakalayıp baytları toplayarak doğrulayın.

Bant Genişliğini Azaltma Kontrol Listesi

  1. Gecikmenin izin verdiği yerlerde örnekleri daha az sayıda, daha büyük mesajlarda gruplayın.
  2. Kompakt payload'lar kullanın: kısa JSON anahtarları, CBOR veya Protobuf. Bkz. MQTT payload formatı.
  3. MQTT 5 ile cihaz topic'lerini kısaltın veya topic alias kullanın.
  4. QoS'u topic bazında seçin: ara sıra kaybın kabul edilebildiği sık telemetri için QoS 0, olaylar ve komutlar için QoS 1.
  5. Her mesaj için yeniden bağlanmak yerine bağlantıları açık tutun ve kalıcı oturumlar kullanın.
  6. Keep alive'ı, ağınızın NAT zaman aşımının izin verdiği en uzun değere ayarlayın.
  7. Değerler sabitken sabit bir hızda değil, değişiklik olduğunda publish edin.
  8. Gereksiz aboneliklerden kaçının: bir cihazdaki wildcard aboneliği eşleşen her mesajı alır ve bu da downlink verisine mal olur.

Verimli Cihazları ConnectMQ'da Çalıştırın

ConnectMQ, topic alias'lar ve session expiry dahil MQTT 3.1.1 ve 5.0'ı, Let's Encrypt sertifikasıyla 8883 numaralı port üzerinden TLS ile destekler; böylece yukarıdaki optimizasyonlar özel bir yapılandırma gerektirmeden çalışır. Ücretsiz herkese açık MQTT broker üzerinde prototip oluşturun, ardından gerçek trafiği özel bir broker'a karşı ölçün. Protokolde yeniyseniz MQTT eğitimi temelleri ele alıyor.

ConnectMQ ile Başlayın

Yönetilen bir MQTT broker, sunucu operasyonları yerine cihaz verimliliğine odaklanmanızı sağlar. app.connectmq.com adresinde kredi kartı gerektirmeden ücretsiz bir Serverless broker oluşturun ve cihazlarınızın tam olarak ne gönderdiğini görmek için canlı topic gezginini kullanın. Daha kapsamlı bir karşılaştırma için bulut MQTT broker seçme rehberimizi okuyun.

Sık Sorulan Sorular

MQTT mesaj başına ne kadar ek yük ekler?

MQTT katmanında bir PUBLISH, onaylardan önce QoS 0'da 4 bayt artı topic adı, QoS 1 ve 2'de ise 6 bayt artı topic ekler. TCP/IP ve TLS bunun üzerine paket başına kabaca 60 bayt veya daha fazlasını ekler.

TLS, MQTT'yi çok daha maliyetli hale getirir mi?

Mesaj başına TLS 1.3, kayıt başına yaklaşık 22 bayt ekler ve bu makul bir miktardır. Daha büyük maliyet, her yeni bağlantıda birkaç kilobaytlık el sıkışmasıdır; bu nedenle sık sık yeniden bağlanmak yerine bağlantıları açık tutun.

MQTT keep alive ne kadar veri kullanır?

Bir ping değişimi MQTT katmanında birkaç bayta mal olur, ancak TCP, IP ve TLS ile yaklaşık 170 bayta ulaşır. Boştaki bir bağlantıda 60 saniyelik aralıkla bu, günde kabaca 240 KB eder.

QoS 0 her zaman en ucuz seçenek midir?

Bayt açısından evet, çünkü hiç onay paketi göndermez. Ancak kaybolan mesajlar uygulamanızı verileri yeniden göndermeye veya yoklama (polling) yapmaya zorluyorsa, QoS 1 genel olarak daha ucuza gelebilir.

İlgili yazılar

MQTT'yi Kim İcat Etti? Petrol Boru Hatlarından IoT'ye Uzanan Tarih

MQTT, 1999'da IBM'den Andy Stanford-Clark ve Arcom'dan Arlen Nipper tarafından petrol boru hatlarını uydu üzerinden izlemek için icat edildi. Açık kaynağa, OASIS'e, ISO'ya ve bugünün yönetilen bulut broker'larına uzanan yolculuğunu izleyin.

7 dk okuma

MQTT Maksimum Mesaj Boyutu: Sınırlar ve Büyük Payload Stratejileri

MQTT teknik olarak 256 MB'lık bir paket taşıyabilir, ancak broker'lar, istemci kütüphaneleri ve cihazlar çok daha düşük sınırlar uygular. Gerçek sınırların nerede olduğunu, aşıldıklarında ne olduğunu ve büyük payload'ların nasıl gönderileceğini öğrenin.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.