Bir MQTT benchmark'ı çok hızlı sayı üretir. Güvenebileceğiniz sayılar üretmek ise daha zordur. Yanıltıcı sonuçların çoğu aynı birkaç hatadan doğar: ortalamaları aktarmak, broker yerine yük üreticiyi ölçmek, coordinated omission'ı görmezden gelmek ve aynı şekilde kurulmamış çalıştırmaları karşılaştırmak.
Bu rehber her tuzağı tek tek ele alıyor, kendi verilerinizde nasıl tespit edeceğinizi gösteriyor ve sonuçları tekrarlanabilir kılan bir rapor şablonuyla bitiyor. Halihazırda bir test çalıştırdığınızı varsayıyoruz; çalıştırmadıysanız MQTT broker yük testi ile başlayın.
Ortalamalar yavaş mesajları gizler
Gecikme hiçbir zaman normal dağılmaz. Yük altındaki bir broker mesajların çoğunu birkaç milisaniyede, küçük bir kısmını ise yüzlerce milisaniyede teslim eder — bir garbage collection duraklaması, diske yazma ya da yeniden iletim sırasında. Ortalama iki grubu karıştırıp hiçbirini anlatmayan bir sayı üretir.
| Çalıştırma | Ortalama | p50 | p99 | Maks. |
|---|---|---|---|---|
| A | 6 ms | 4 ms | 12 ms | 30 ms |
| B | 6 ms | 3 ms | 140 ms | 900 ms |
(Örnek değerler.) İki çalıştırmanın ortalaması aynı, ama B'de her yüz mesajdan biri saniyenin onda birinden fazla gecikmeyle ulaşıyor. Saniyede bir publish yapan bir cihaz için bu, yaklaşık her iki dakikada bir fark edilir bir gecikme demektir.
Sizi dürüst tutan kurallar:
- Yüzdelikleri raporlayın: p50 (tipik), p99 (kuyruk), maks. (gözlemlenen en kötü durum). p99.9'u yalnızca yeterli örneğiniz varsa ekleyin.
- Yüzdeliklerin asla ortalamasını almayın. On p99 değerinin ortalaması, birleşik verinin p99'u değildir — ham örnekleri ya da histogramları birleştirin.
- Örnek sayısını kontrol edin. 100 mesajın p99'u tek bir mesajdır. Her çalıştırmada binlerce örnek toplayın.
Coordinated omission
Coordinated omission, bir benchmark'ın gerçekte olduğundan iyi görünmesinin en yaygın nedenidir. Yük üretici bir sonraki isteği göndermeden önce yanıtı beklediğinde ortaya çıkar. Broker 500 ms takılırsa, senkron çalışan bir publisher bir yavaş mesaj kaydeder — ve gerçek bir filonun o yarım saniyede göndereceği diğer 49 mesajı hiç göndermez. Hepsi yüksek gecikme görecek olan bu mesajlar verilerde hiç yer almaz.
Gerçek cihazlar broker ile koordine olmaz. Bir sensör, son PUBACK gelmiş olsun ya da olmasın kendi takvimine göre publish eder. Bunu yeniden üretmek için gecikmeyi mesajın sokete gerçekten verildiği andan değil, planlanan gönderim zamanından itibaren ölçün:
import json, statistics, time, uuid
import paho.mqtt.client as mqtt
HOST, PORT = "broker.connectmq.com", 1883
TOPIC = f"testmqtt/bench-{uuid.uuid4().hex[:8]}/latency"
N, RATE = 20000, 500 # mesaj sayısı, saniyedeki mesaj
samples = []
def on_message(client, userdata, msg):
intended = json.loads(msg.payload)["t"]
samples.append((time.perf_counter() - intended) * 1000)
sub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
sub.on_message = on_message
sub.connect(HOST, PORT)
sub.subscribe(TOPIC, qos=1)
sub.loop_start()
pub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
pub.max_queued_messages_set(0) # 0 = istemci tarafında sınırsız kuyruk
pub.connect(HOST, PORT)
pub.loop_start()
time.sleep(1)
start = time.perf_counter()
for i in range(N):
intended = start + i / RATE # gerçek bir cihazın izleyeceği takvim
delay = intended - time.perf_counter()
if delay > 0:
time.sleep(delay)
pub.publish(TOPIC, json.dumps({"i": i, "t": intended}), qos=1)
time.sleep(5)
q = statistics.quantiles(samples, n=1000) # 999 kesim noktası
print(f"received {len(samples)}/{N}")
print(f"p50 {q[499]:.1f} ms p99 {q[989]:.1f} ms p99.9 {q[998]:.1f} ms max {max(samples):.1f} ms")Publisher takvimin gerisine düşerse — broker ya da ağ geri ittiği için — gecikmeli her mesaj bu gecikmeyi kendi ölçümünde taşır. Çıktıyı, publish anında time.perf_counter() damgası basan bir sürümle karşılaştırın: planlanan zamana göre p99 çok daha yüksekse, broker takılıyordu ve basit ölçüm bunu gizliyordu.
Broker'ı mı ölçüyorsunuz, istemciyi mi?
CPU'su, soketleri ya da ağ bant genişliği tükenen bir benchmark makinesi, tıpatıp broker limitine benzeyen bir plato üretir. Broker'ı suçlamadan önce yük üreticiyi kontrol edin:
- Üreticinin CPU'su. Bir çekirdek %100'de duruyorsa (tek iş parçacıklı istemcilerde sık görülür; örneğin saniyede yüzlerce mesajı tek bir paho ağ döngüsünün işlemesi), tavan sizin tarafınızdadır. İstemcileri birden fazla süreç ya da makineye dağıtın.
- Yuvarlak sayılarda platolar. 1.024, 4.096 veya 28.000–64.000 civarında duran bağlantı sayıları genellikle istemci makinesindeki dosya tanımlayıcı ya da geçici (ephemeral) port limitlerine işaret eder.
ulimit -ndeğerini artırın veya kaynak IP ekleyin. - Ağ arayüzü. Mesaj hızını hattaki boyutla çarpın (paket boyutu hesaplayıcı PUBLISH başına tam bayt sayısını verir) ve TLS ek yükü dahil bağlantı kapasitesiyle karşılaştırın.
- İki makine testi. Aynı yükü, her biri yarı hızda olan iki üreticiden gönderin. Toplam throughput artıyorsa darboğaz tek üreticiydi.
Hikâyenin geri kalanını broker tarafı anlatır: CPU, bellek, bağlantı sayısı ve mesaj hızlarını (örneğin $SYS topic'lerinden ya da Prometheus'tan) istemci tarafı sayıların yanına kaydedin. %30 CPU'da çalışıp throughput grafiği kilitlenmiş bir broker başka bir şeyi bekliyordur.
Saatler, ısınma ve diğer sessiz bozulmalar
- Saat kayması. Publisher ve subscriber farklı makinelerde çalışıyorsa, uçtan uca gecikme saatleri arasındaki farkı da içerir. NTP saatleri en iyi ihtimalle birkaç milisaniye içinde tutar — çoğu zaman daha kötü. Publisher ve subscriber'ı tek süreçte çalıştırarak ölçün ya da gidiş-dönüş süresi kullanın. Ayrıntılar: MQTT saat ve zaman damgası sorunları.
- Isınma. İlk saniyeler TCP ve TLS el sıkışmalarını, JIT derlemeyi ve önbellek ıskalarını içerir. Bir ısınma süresini atın ya da ayrı raporlayın.
- Çok kısa çalıştırmalar. 30 saniyelik bir çalıştırma, kalıcılık anlık görüntüleri veya log rotasyonu gibi periyodik olayları kaçırabilir. Her yük seviyesini dakikalarca tutun; saatler için bir soak testi kullanın.
- Kaybolan mesajlar. Yalnızca ulaşan mesajlardan hesaplanan yüzdelikler, yavaş olanlar düşürüldüyse harika görünür. Gecikmenin yanında her zaman
alınan / gönderilenoranını raporlayın. - Farklı QoS. QoS 0, 1 ve 2'nin paket sayıları ve maliyetleri çok farklıdır; sonuçları QoS seviyeleri arasında aynı testmiş gibi asla karşılaştırmayın. Bkz. QoS 0 vs 1 vs 2 benchmark.
Kötü bir sonucu tanımak
| Verideki belirti | Olası neden | Nasıl doğrulanır |
|---|---|---|
| Broker CPU'su düşükken throughput sabit | Yük üretici doymuş | Üreticinin CPU'suna bakın; iki üreticiyle tekrarlayın |
| QoS 0'da alınan < gönderilen | İstemci ya da broker baskı altında mesaj düşürüyor | QoS 1 ile tekrarlayıp sayıları karşılaştırın |
| p99 iyi, maks. çok büyük | Tek bir takılma (GC, failover, disk) | Sadece histogram değil, gecikmeyi zamana göre çizin |
| p50 çalıştırma boyunca sürekli artıyor | Kuyruk birikiyor (yavaş tüketici) | Broker'ın kuyruk / inflight metriklerini izleyin |
| Aynı çalıştırmalar arasında %30 fark | Paylaşımlı veya gürültülü ortam | Üç kez çalıştırın; izole bir broker'da test edin |
| Negatif ya da imkânsız derecede düşük gecikme | Farklı makinelerin saatleri | Tek süreç içinde ölçün |
MQTT benchmark sonuçları nasıl raporlanır
Kurulumu belirtilmemiş bir sayı ne tekrarlanabilir ne karşılaştırılabilir. En azından şunları raporlayın:
| Alan | Örnek |
|---|---|
| Broker, sürüm, dağıtım | Broker X 2.x, 4 vCPU / 8 GB, tek node |
| İstemci aracı ve sürümü | emqtt-bench / paho-mqtt 2.x ile özel script |
| Yük üretici | 2 makine, aynı bölge, CPU zirvesi %55 |
| Ağ ve taşıma | Aynı bölge, TCP 1883 (veya TLS 8883) |
| Protokol ve QoS | MQTT 5, QoS 1, clean start |
| İş yükü | 1.000 publisher, her biri 1 msg/s, 512 B JSON, 1:1 topic'ler |
| Süre | 5 dk ısınma hariç, 20 dk ölçüm |
| Sonuçlar | Gönderilen/alınan throughput, p50, p99, p99.9, maks., hatalar |
| Ham veri | Histogram veya CSV bağlantısı |
İki alışkanlık raporları çok daha faydalı kılar:
- Gecikmeyi zamana göre çizin. Histogram, yavaş mesajların ne zaman yaşandığını gizler. Zaman serisi ise kuyruğun sabit bir özellik mi yoksa birkaç olaydan mı ibaret olduğunu gösterir.
- Doyma noktasını gösterin. Tek bir sayı yerine artan yük seviyeleri çalıştırın ve p99'un hedefinizi (örneğin 50 ms) aştığı hızı raporlayın. Kullanılabilir kapasiteniz bu hızdır; mutlak maksimum throughput değil.
Her çalıştırmadan önce hızlı bir kontrol
Uzun bir benchmark başlatmadan önce online MQTT istemcisi ile bağlanın, test topic'inize abone olun ve elle birkaç mesaj publish edin. Bir mesaj gözle görülür şekilde geç geliyorsa ya da abonelik hiçbir şey almıyorsa önce bunu düzeltin — yük testi size bundan fazlasını söylemeyecektir.
Benchmark topic'inizi tarayıcıda test edin
Benchmark'lar ancak arkalarındaki sorular kadar iyidir. Planlanan gönderim zamanından ölçün, yük üreticiyi gözden kaçırmayın, yüzdelikleri teslim sayıları ve tam kurulumla birlikte raporlayın; MQTT sayılarınız onları yeniden üretmeye çalışan bir sonraki kişiye — gelecekteki kendiniz dahil — dayanacaktır.
Sıkça sorulan sorular
MQTT benchmark'ında ortalama gecikme neden yanıltıcıdır?
Gecikme dağılımları çarpıktır: mesajların çoğu hızlı, birkaçı ise çok yavaştır. Ortalama iki grubu karıştırır ve cihazların ile kullanıcıların gerçekten fark ettiği yavaş kuyruğu gizler. Bunun yerine p50, p99 ve maksimumu raporlayın.
MQTT benchmark'ında coordinated omission nedir?
Yük üreticinin bir sonraki mesajı göndermeden önce yavaş bir yanıtı beklemesiyle oluşur. Takılma, o sürede gönderilmesi gereken her mesaj için değil yalnızca bir kez ölçülür; bu yüzden araç, gecikmeyi tam da broker zorlandığında olduğundan düşük gösterir.
Güvenilir bir p99 için kaç mesaj gerekir?
Her çalıştırmada en az birkaç bin örnek. 100 mesajda p99 tek bir örnektir. p99 için 10.000 veya daha fazlasını, p99.9 vermek istiyorsanız 100.000 veya daha fazlasını hedefleyin.



