Daily MaverickFormer ‘crown prince of the Kruger’ Park found guilty of rhino poachingThe Jerusalem PostTwo Arab Israelis, one PA resident indicted for stealing IDF shoulder-fired MATADOR missileBollywood HungamaRonit Roy leases Andheri west office space for Rs 1.39 crores over five yearsESPN📈 NFL draft QB Hot Board: Ranking the top 15 passersInquirerAnalyst: VP Duterte didn’t declare P207-M cash, total assets reach P817MESPN Deportes¿Qué necesita tu equipo de NBA? El mayor hueco en cada plantillaRTP DesportoNuno Espírito Santo eleito melhor treinador de setembro do ChampionshipBillboardHow Live Nation’s Hans Schafer Redefined Latin Touring’s Global Potential: ‘It’s Not One-Size-Fits-All’ZDF heuteAktuelle Pressemitteilungen des ZDFColliderThe Next Major Harry Potter RPG Is Officially HereThe Hollywood ReporterDespite BTS Boycott, Grammys Double Down on Controversial New Asian Pop CategoryDeadlineSadie Sink And Lorene Scafaria Eyeing Adaptation Of Emma Cline’s ‘The Guest’ At A24 And Square Peg
The Daily Newsstand · Free, Always
Friday, October 9, 2026

Пять MQTT‑брокеров на AWS: соединения, задержки и поведение под нагрузкой

Translate

Сколько сообщений в секунду выдерживает MQTT‑брокер? Без описания нагрузки этот вопрос почти ничего не говорит. Приём сообщений от множества устройств, доставка одного сообщения тысяче подписчиков и обслуживание сотен тысяч соединений нагружают сервер по‑разному.

Я сравнил Mosquitto, EMQX, FlashMQ, HiveMQ Community Edition и XMQ на одном AWS‑стенде. Меня интересовали доставленная скорость, задержка и потребление CPU и памяти, а также то, что происходит, когда брокер не успевает за заданной нагрузкой.

Сразу обозначу свою заинтересованность: я разработчик XMQ. Генератор нагрузки xmq_scn также входит в этот проект. Поэтому рядом с результатами нужны версии, сценарии, конфигурации и исходные отчёты: читатель должен иметь возможность проверить эксперимент.

Откуда взяты сценарии

За основу взят Open MQTT Benchmark Suite команды EMQX и их сравнение EMQX и Mosquitto от 23 апреля 2023 года. Оттуда выбраны четыре типа тестов: fan‑in, fan‑out, point‑to‑point и concurrent connections. Это известный набор сценариев с явно заданной структурой нагрузки, который можно применить к разным брокерам.

Подобные типы нагрузки используются и командой HiveMQ: в описании их автоматизированного бенчмаркинга опубликованы сценарии Idle Connections, PUBLISH fan‑in и PUBLISH fan‑out. Это подтверждает практическую применимость этих типов тестов. Конкретные параметры и топология у HiveMQ отличаются: часть сценариев выполняется на кластере, поэтому здесь заимствованы не их результаты и не конфигурация стенда.

С тех пор версии брокеров изменились. Поэтому из публикации 2023 года я использую структуру сценариев и подход к выбору стенда, а численные результаты измеряю заново. Все сравнительные таблицы ниже относятся к моей AWS‑серии от 7 октября 2026 года. Генератор здесь — xmq_scn, в исходной публикации — XMeter.

Есть и конкретные отличия: в исходной статье сервер — c5.4xlarge, у меня — c5n.4xlarge с тем же числом vCPU. Point‑to‑point в этой серии увеличен с 50 000 до 100 000 сообщений/с, connections уменьшен с миллиона до 500 000 соединений. Fan‑in и fan‑out сохраняют структуру и целевые скорости Enterprise Set. Все мои сценарии используют MQTT 5. Более высокая нагрузка относится к конкретным параметрам: например, P2P здесь передаёт вдвое больше сообщений, чем исходный Enterprise Set. Продолжительность в исходной статье — 30 минут; здесь — 10 минут для fan‑in и point‑to‑point, 5 минут для fan‑out. Это применение исходных сценариев с указанными изменениями, а не точное повторение эксперимента 2023 года.

Участники и стенд

Брокер

Тестируемая версия

Mosquitto

2.1.2

EMQX

6.3.1, пакет emqx‑enterprise, community license по записи запуска

FlashMQ

1.27.2

HiveMQ Community Edition

2026.5

XMQ

0.9.20 pre‑release, сборка dbe0a57

Брокер и генератор работали на отдельных EC2 c5n.4xlarge: 16 vCPU, то есть 8 физических ядер с двумя аппаратными потоками. Оба сервера находились в одной placement group, с ENA. ОС — Ubuntu 26.04; в отчёте брокера указан kernel 7.0.0–1013-aws. Привязки процессов к CPU не было. Перед каждым сценарием брокер перезапускался, остальные брокеры останавливались.

Все сценарии передачи сообщений использовали MQTT 5, QoS 1 и payload размером 16 байт. Клиент работал с 29 дополнительными исходными адресами по записи стенда. Это позволяет распределить большое количество TCP‑соединений между исходными адресами. Лимиты файловых дескрипторов были повышены.

Брокеры тестировались с настройками для большой нагрузки. У Mosquitto max_queued_messages=0 снимает лимит количества сообщений в очереди, а max_inflight_messages=65534 повышает предел сообщений в полёте. По записи запуска значение 0 в Mosquitto 2.1 оставляло входную квоту нулевой, поэтому для итоговой серии использовано явное значение 65534. Это сравнение настроенных экземпляров, а не установок с настройками по умолчанию.

У FlashMQ задано 16 рабочих потоков. У EMQX увеличены лимиты mailbox и очереди сообщений до 100000, max_inflight=128, стратегия shared subscription — round_robin. HiveMQ использовал JVM с -Xms2g -Xmx20g -XX:MaxDirectMemorySize=5g. У XMQ настроены три send‑потока, четыре receive‑потока и два delivery‑потока. Более подробное описание стенда есть на сайте; для повторения именно этой серии ориентироваться нужно на приложенные записи от 7 октября.

Что означают числа

Задержка в таблицах — значение Average из отчёта xmq_scn. Оно рассчитывается как сумма зарегистрированных задержек, делённая на число зарегистрированных доставок. Начало теста включено в среднее. Временные графики показывают среднее внутри каждого интервала.

Строка Median в исходных отчётах имеет другой смысл: это центральное значение после сортировки средних по интервалам. При чётном числе интервалов выбирается верхнее из двух центральных значений. Это не медиана задержек отдельных сообщений; p95 и p99 эти отчёты не содержат.

Генератор регистрирует время перед вызовом публикации и снимает его при получении сообщения подписчиком. Сопоставление выполняется через FIFO‑очереди времён отправки; для fan‑in используется общая очередь. Поэтому при потерях, дубликатах или изменении порядка доставки оценка не равнозначна измерению по уникальному идентификатору каждого сообщения. В этой статье числа трактуются как измерения данного генератора, а не как независимые распределения задержек всех сообщений.

CPU указан в процентах одного аппаратного потока: 100% приблизительно соответствует одному занятому vCPU, 400% — четырём. Память — максимум RSS процесса брокера, зарегистрированный сборщиком. Это не вся память хоста и не оценка общей стоимости эксплуатации. Обозначения MB и GB ниже следуют единицам исходных отчётов.

500 тысяч соединений

Первый сценарий устанавливает 500 000 соединений с целевой скоростью 5000 подключений в секунду. Здесь измеряется время подключения, а не доставки сообщения.

Брокер

Успешных подключений

Среднее время подключения

CPU, среднее

Пик RSS

Mosquitto

500 000

1004 мкс

18%

2,41 GB

EMQX

500 000

720 мкс

359%

10,06 GB

FlashMQ

500 000

347 мкс

33%

2,13 GB

HiveMQ CE

500 000

4088 мкс

107%

4,06 GB

XMQ

500 000

340 мкс

52%

1,27 GB

Основной цикл обработки MQTT в Mosquitto однопоточный: в сценариях передачи сообщений он не распределяет эту работу между всеми 16 vCPU. Поэтому около 100% CPU означает насыщение одного ядра, а не наличие доступного резерва для этого цикла.

Все пять брокеров установили заданное число соединений. FlashMQ и XMQ показали близкое среднее время подключения. Минимальный зарегистрированный пик RSS в этой серии — у XMQ; минимальная средняя загрузка CPU — у Mosquitto.

Среднее скрывает различия во времени. У Mosquitto большинство интервалов лежит около 300–334 мкс, но один достигает 7227 мкс. У HiveMQ CE интервальные средние меняются от 719 до 14 809 мкс. Поэтому одного итогового числа недостаточно для характеристики подключения.

Строка Average у всех участников показывает 4545 подключений/с. Она получена делением 500 000 на 11 полных десятисекундных интервалов, включая последний неполный. Её нельзя трактовать как точную скорость завершения подключения или предел производительности брокера.

Fan‑in: много издателей, общая группа подписчиков

50 000 издателей публикуют по одному сообщению в секунду, каждый в свой topic. 500 подписчиков разделяют сообщения через $share/benchmark/test/#. Каждое сообщение должно попасть к одному участнику группы. Целевая скорость — 50 000 доставок/с, длительность сценария — 10 минут.

Брокер

Скорость из отчёта, доставок/с

Средняя задержка

CPU, среднее

Пик RSS

Mosquitto

49 992

210 мкс

88%

258 MB

EMQX*

1613*

84,400 с*

965%

12,85 GB

FlashMQ

49 992

207 мкс

221%

246 MB

HiveMQ CE

49 908

971,810 мс

185%

1,91 GB

XMQ

49 992

211 мкс

228%

192 MB

EMQX: таблица содержит только пять непустых минутных интервалов, хотя запуск сценария занимал около десяти минут. Значение 1613/с рассчитано генератором по этим пяти интервалам и не является средней скоростью за все десять минут. Зафиксировано 484 103 доставки. По разбору автора прогона, при достижении force_shutdown.max_heap_size EMQX начал отключать подписчиков. Это прекращение доставки при перегрузке, а не подтверждённое падение всего брокера.

Mosquitto, FlashMQ и XMQ дают очень близкие задержки: 207–211 мкс. На основании одного запуска различие в несколько микросекунд не стоит превращать в рейтинг. При этом Mosquitto использует меньше CPU, а XMQ — меньше RSS.

HiveMQ CE поддерживает близкую к целевой доставленную скорость, но интервальная задержка после первого интервала остаётся около 972 мс. Постоянная задержка такого размера сама по себе не доказывает нехватку пропускной способности: причина может относиться к очередям, настройкам или методике измерения. Для объяснения нужен отдельный контрольный тест.

EMQX в этом запуске не поддержал целевую скорость: число доставок в последовательных интервалах уменьшается, а оценка задержки растёт от 16,6 до 236,8 секунды. Это результат конкретной конфигурации и генератора. Разбор показал срабатывание ограничения force_shutdown.max_heap_size и отключение подписчиков. Увеличение лимита в дополнительных проверках не устранило непрерывный рост задержки: уже к середине теста она была неприемлема для задачи автора. Поэтому само по себе повышение лимита памяти не решило проблему этого сценария. Численные результаты дополнительных проверок здесь не приводятся; таблица относится к исходному AWS‑запуску. Этот результат нельзя обобщать на другие конфигурации EMQX.

Fan‑out: одно сообщение, тысяча получателей

Пять издателей отправляют по 50 сообщений/с в пять topics. Тысяча подписчиков получает все эти сообщения: 250 входящих публикаций превращаются в 250 000 доставок/с. Сценарий работает пять минут и использует всего 1005 соединений.

Брокер

Доставок/с

Средняя задержка

CPU, среднее

Пик RSS

Mosquitto

176 577

44,047 с

100%

73 MB

EMQX

249 972

5,368 мс

1491%

617 MB

FlashMQ

249 993

2,180 мс

567%

28 MB

HiveMQ CE

249 890

5,229 мс

1068%

1,58 GB

XMQ

249 993

1,415 мс

376%

45 MB

В этом сценарии XMQ показывает минимальную среднюю задержку среди участников и меньшую загрузку CPU среди брокеров, достигших приблизительно целевой скорости. FlashMQ имеет минимальный RSS. Задержка XMQ примерно на 35% ниже, чем у FlashMQ: 1,415 против 2,180 мс.

Средние HiveMQ CE и EMQX близки, но динамика отличается. У HiveMQ CE первый интервал — 20,347 мс, последующие — около 3,5 мс. У EMQX все интервалы лежат около 4,9–5,5 мс. Среднее за весь запуск включает стартовый участок; выбрасывать его только у одного участника было бы некорректно.

Mosquitto достигает примерно 176,6 тысячи доставок/с и занимает один vCPU. Его интервальная задержка растёт от 4,4 до 83,7 секунды. Такая динамика согласуется с накоплением очереди, когда обработка отстаёт от предложенной нагрузки. Итоговые 44 секунды описывают этот пятиминутный запуск, а не постоянную задержку в устойчивом режиме. Расположение и размер очередей данным отчётом не установлены.

Point‑to‑point: сто тысяч сообщений в секунду

50 000 издателей и 50 000 подписчиков образуют пары, у каждой свой topic. Издатель отправляет два сообщения в секунду. Итого — 100 000 соединений и целевые 100 000 доставок/с в течение десяти минут.

Брокер

Доставок/с

Средняя задержка

CPU, среднее

Пик RSS

Mosquitto

99 449

2,760 с

97%

615 MB

EMQX

99 700

635,977 мс

1503%

4,93 GB

FlashMQ

99 915

214 мкс

448%

493 MB

HiveMQ CE

99 862

4,686 мс

1046%

2,83 GB

XMQ

99 913

222 мкс

429%

387 MB

FlashMQ и XMQ поддерживают примерно заданную скорость с задержкой около 0,2 мс. В этом запуске FlashMQ немного быстрее, XMQ использует немного меньше CPU и памяти. Значимость небольших различий требует повторений.

У HiveMQ CE особенно заметен старт: первый минутный интервал имеет среднее 43,677 мс, остальные — 340–363 мкс. Итоговое среднее 4,686 мс нельзя подавать как задержку установившегося режима. Возможно влияние прогрева JVM, однако измерений для подтверждения этой причины здесь нет.

EMQX в большинстве интервалов держит около 100 тысяч доставок/с, но задержка остаётся около 0,62 секунды при загрузке CPU около 1500%. Mosquitto также держится близко к заданной скорости после старта, с задержкой порядка 2,7–3,1 секунды и почти полностью занятым одним vCPU. Эти данные не показывают максимальную достижимую скорость каждого брокера: для этого потребуется серия с постепенным повышением нагрузки.

На графике использована логарифмическая шкала. EMQX fan‑in отмечен как неполная серия с отключением подписчиков; визуальное сравнение этого столбца не заменяет проверку исходного запуска.

Изменение задержки по интервалам

Изменение задержки по интервалам

Временные графики помогают увидеть рост задержки Mosquitto в fan‑out, рост задержки EMQX fan‑in перед прекращением доставки и стартовый участок HiveMQ CE в point‑to‑point. Масштабы осей у панелей различаются.

Persistence: одинаковый сценарий, разные способы хранения

К четырём типам нагрузки добавлен тест persistent sessions: 60 000 издателей и 60 000 подписчиков, 60 000 topics, по одному сообщению в секунду на издателя, 10 минут. MQTT 5, QoS 1, payload 16 байт; у обеих групп clean_session=false. Хранилища очищались перед запуском; для EMQX потребовалось исправить процедуру очистки и повторить тест, как описано ниже.

Этот сценарий сложнее сравнивать, потому что брокеры сохраняют состояние разными способами. В тестируемых конфигурациях Mosquitto и FlashMQ периодически сохраняют snapshot; EMQX, HiveMQ CE и XMQ настроены на сохранение сообщений через свои механизмы persistence. Snapshot тоже может содержать сообщения и состояние сессий, но периодическая запись снимка не равнозначна записи каждого изменения.

Брокер

Режим хранения в тесте

Доставок/с

Средняя задержка

CPU, среднее

Пик RSS брокера

Mosquitto

Snapshot по autosave_interval и при остановке

59 844

843,004 мс

97%

642 MB

EMQX

Durable sessions, после полной очистки хранилища

59 655

23,753 мс

1265%

5,08 GB

FlashMQ

Snapshot в storage_dir периодически и при остановке

59 941

208 мкс

246%

587 MB

HiveMQ CE

Файловое persistence

58 368

9,135 с

1398%

22,09 GB

XMQ

Локальный Redis, appendfsync everysec

59 933

216 мкс

284%

460 MB

FlashMQ и XMQ в этих конфигурациях держат примерно целевую скорость с близкой оценкой задержки. Однако эти числа не доказывают равные гарантии сохранности. Для XMQ измерен процесс брокера: CPU и RSS отдельного Redis в таблицу не включены, поэтому это не полная стоимость его persistence.

У HiveMQ CE интервальная задержка растёт от 3,6 до 14,6 секунды, а зарегистрированный пик RSS достигает 22,09 GB. Mosquitto держит близкую к целевой скорость с интервальной задержкой около 0,8 секунды. По одним итоговым числам нельзя установить, какая часть затрат приходится на хранение, а какая — на обработку сообщений и очереди.

Первый запуск EMQX с durable sessions не принял подключение: генератор получил Server not available. Причиной оказалась неполная очистка состояния перед тестом: shards удалялись, но старые файлы Mnesia оставались. После полной очистки тест повторён в AWS с прежними настройками и успешно завершён; в таблице приведён исправленный запуск. Он показал 59 655 доставок/с, среднюю задержку 23,753 мс и пик RSS 5,08 GB. Отказ первого запуска относится к подготовке стенда, а не к измеренной производительности EMQX. Отключение подписчиков в fan‑in связано с ограничением heap и является отдельным случаем, не связанным с очисткой Mnesia.

У XMQ важно разделять отказ брокера и отказ хранилища. Если завершается процесс XMQ, а Redis продолжает работать, уже переданные Redis записи сохраняются. XMQ использует окно отложенной записи 10 мс: если подписчик успел подтвердить сообщение, запись для повторной доставки уже не нужна и не создаётся. Если подтверждения нет, XMQ передаёт запись в Redis.

10 мс — задержка перед постановкой записи, а не безусловная верхняя граница потери при любой скорости Redis. В конфигурации этой серии max_queued_writes=1000 ограничивает окно неподтверждённых записей; при 60 000 сообщений/с это соответствует примерно 16,7 мс входящего потока. Время фактического завершения записи зависит также от Redis и планирования потоков.

Для Redis в режиме Durable используется AOF с appendfsync everysec: обычное окно между fsync — около секунды. Отказ только процесса Redis при работающей ОС отличается от отказа машины Redis: во втором случае возможна потеря последних записей, ещё не синхронизированных с диском. В этой AWS‑серии Redis указан как локальный, поэтому отказ всего хоста XMQ затрагивает и Redis; случай «падает хост XMQ, Redis работает» относится к размещению Redis на другом хосте.

Этот тест показывает производительность выбранных режимов, но не проверяет сохранность после аварии. Для проверки границ потери нужны отдельные сценарии восстановления после штатного перезапуска, аварийного завершения брокера и отказа хоста хранилища.

Что этот эксперимент позволяет выбрать

Универсального победителя эти четыре сценария не дают.

В fan‑in Mosquitto, FlashMQ и XMQ показали близкую задержку, причём Mosquitto потратил меньше CPU. В fan‑out минимальное среднее время доставки показал XMQ, а минимальный RSS — FlashMQ. В point‑to‑point FlashMQ и XMQ имеют близкие субмиллисекундные результаты; у HiveMQ CE после стартового интервала среднее внутри минутных интервалов тоже меньше миллисекунды. Все пять брокеров установили 500 тысяч соединений.

Для выбора важны не только эти числа. Здесь не сравниваются кластеризация, интеграции, удобство эксплуатации, TLS, большие payload, длительные сессии и восстановление после сбоя. Это один запуск каждой комбинации брокера и сценария, а не серия измерений с доверительными интервалами. Генератор работал на отдельной машине, но отсутствие ограничения с его стороны нельзя доказать только суммарной загрузкой CPU.

Результаты persistence приведены отдельно с описанием способов хранения. Они характеризуют выбранные конфигурации и не образуют рейтинг при одинаковых гарантиях сохранности.

Как проверить на своей системе

Сценарии и генератор доступны в репозитории XMQ, описание инструмента — на странице MQTT Test Suite. xmq_scn работает с MQTT‑брокером по адресу и порту; для сравнения используется один сценарий и один клиент.

Параметры сценариев этой серии:

  • 500K-Connections-5000-rate.json: 500 000 подключений, 5000/с.

  • Fan-In-50K-500-50K-50K.json: 50 000 издателей, 500 shared subscribers, 50 000 сообщений/с, 600 секунд.

  • Fan-Out-5-1000-5-250K-5min.json: 5 издателей, 1000 подписчиков, 250 000 доставок/с, 300 секунд.

  • Point-To-Point-50K-50K-50K-100K.json: 50 000 пар, 100 000 сообщений/с, 600 секунд.

  • Point-To-Point-60K-persistent.json: 60 000 пар с persistent sessions, 60 000 сообщений/с, 600 секунд.

При повторении сохраняйте точные версии, конфигурации, параметры хоста и полный вывод. Разница между запланированной и полученной скоростью не равна автоматически потере сообщений: часть может оставаться в очередях, а публикация — ограничиваться обратным давлением.

Если попробуете эти сценарии на своей нагрузке, мне интересны результаты и замечания к методике. Для знакомства с XMQ доступны пакеты и Docker‑инструкция в README. Поделиться воспроизводимым случаем можно через issues.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.