High performance
Instant Messaging Systems
ITSumma corporate blog
Apache
Big Data
Comments 40
+2
Незаслуженно обделили Apache ActiveMQ Artemis, он во многом перспективнее RabbitMQ при функциональной совместимости решения.
+1
спасибо, обязательно посмотрим!
это серия из 5-и статей которая сравнивает именно кролика и кафку, но мы посмотрим как можно вписать
0
Если у Артемиды AMQP 1.0 «под капотом», то о какой «функционально совместимости» (с «кроликом», как я понимаю) может идти речь?!

Что касается самой статьи, то практически всё, что в ней сказано про RabbitMQ (за исключением, возможно, «масштабируемости»), собственно, к самому «кролику» имеет весьма опосредованное отношение. Оно всё про AMQP «нулевой» серии.

А поскольку, авторы, судя по всему, в AMQP разбираются «ниочинь» (это я про оригинал), то — лично у меня — возникает «смешенное чувство» от «рассуждений» про «использует push», про «конкурирующих получателей» и т.п.
0
В статье было сказано про интернет вещей и протоколы STOMP, MQTT. В этом контексте и прокомментировал. В плане версии AMQP все верно, но в java приложениях его используют через JMS клиентов и в этом случае решения функционально совместимы.
0
Я понял. Только нужно помнить, что если «под капотом» не AMQP «нулевой» серии, то у вас нет ни exchange'ей, ни к ним «привязанных» очередей и т.п. Поэтому вся «функциональная совместимость» — в таком случае — сводится к «мы умеем слать сообщения».

… но в java приложениях его используют через JMS клиентов и в этом случае решения функционально совместимы.

Вообще-то нет. Т.к. на «движок» AMQP 0.9, 0.10 «ложится» практически любой messaging — в том числе, и AMQP 1.0. А вот наоборот — уже нет. Т.е. про все «плюшки» маршрутизации «на брокере» уже можно будет забыть.

Либо у нас сильно разное понимание «функциональной совместимости».
0
Спасибо что просветили! Не являюсь знатоком протоколов AMQP 0.9, 0.10 vs AMQP 1.0. Благодаря вашим замечаниям, по результатам чтения документации сложилось впечатление что главное отличие в том что AMQP 1.0 концентрируется на описании протокола и не регламентирует архитектуру брокера, exchanges и bindings. Но при этом в AMQP 1.0 возможны взаимодействия точка-точка без брокера, что может лучше подходить для mesh network в некоторых сценариях обмена IoT устройств.

За свою практику приходилось работать с Tibco EMS, Amazon SQS, Kafka, Solace(только через JMS API), Universal Messaging(Nirvana) и когда нужен сложный роутинг по контенту сообщений, то он выносился на уровень приложения либо на Apache Camel route. Бриджами баловались только в Tibco, в остальных системах без них спокойно жили. Так что без маршрутизации на брокере как-то обходились. Часть систем были банковским ПО, часть проектов распределенные «числодробилки».

На практике от сервиса очередей сообщений требуется поддержка транзакций, гарантированная доставка с какой-либо из семантик и требуемая системой пропускная способность для персистентных сообщений, еще хорошо если есть «из коробки» поддержка dead letter queue. Сложные же вещи лучше переложить на полноценный message routing engine.

С точки зрения что не получится заменить RabbitMQ на Artemis, при использований всех фич RabbitMQ вы правы. Но если же рассматривать в контексте RabbitMQ vs Kafka или Artemis vs Kafka, то Artemis может лучше подойти для IoT приложений чем RabbitMQ. Так что видимо у нас действительно разное понимание функциональности, совместимости.
+3
Спасибо за статью, много хорошей информации.

Одно дополнение.
Когда вы имеете дело с ИИОТ то важным требованием является возможно апгрейда микросервисов с 0 остановкой (Blue/Green/Canary).
Использование потоковых инструментов типа кафки или кинесиса позволяет деплоить с существенно более простой архитектурой, поскольку поток всегда можно пере-проиграть снова в случае откатов.

Для многих «edge» сервисов мы используем стримы именно по этому поводу.
0
Так при использовании RabbitMQ, audit log также можно реализовать на уровне микросервиса при помощи паттерна EventSourcing. И Вы также можете «перепроиграть» события.
0

Извините за возможный офтопик. Мне нужна очередь для выполнения определенных вычислений (каждая задача относится к конкретному пользователю). Но таким образом, чтобы задачи, относящиеся к одному пользователю, не передавались на обработку одновременно. Есть ли возможность сделать это на какой-то "стандартной" очереди? Или придется делать свое решение? Кафка, судя по описанию, умеет группировать события по признаку, но мне не нравится, что может получиться ситуация, когда один воркер ничего не делает, а второй перегружен задачами.

+3
Это нормально ложится на AMQP «нулевой» серии. Основная идея в том, что вам надо разделить «потребителей», которые производят вычисления (не важно, какого пользователя), и «потребителей», которые осуществляют диспетчеризацию задач на вычисление (для конкретного пользователя). Конечно это все сильно проще «нарисовать», но…

Логика работы «вычислителя» примерно следующая:
1. Из очереди T получаем сообщение m, без ack;
2. На основе данных из сообщения проводим вычисления;
3. Результат вычислений r отсылаем c m.replyTo;
4. Делаем ack на T и переходим к 1.

Логика работы «диспетчера» примерно такая:
1. Из очереди U получаем сообщение t, без ack;
2. Формируем сообщение m = t, m.replyTo = UR;
3. Посылаем m в T;
4. Получаем из UR сообщение r;
5. Делаем ack на U и переходим к 1.

Очередь T – одна на все. Её «слушают» все «вычислители». Кол-во «вычислителей» делать больше чем кол-во пользователей смысла не имеет, т.е. к в T всегда будет не больше сообщений чем пользователей (от каждого, только одно сообщение).

Очереди U/UR — у каждого пользователя свои. «Диспетчер» может быть один на все U/UR (условно, «сложный»), или у каждой U/UR он будет свой (условно, «простой»). Важно, что у конкретной U/UR только один конкретный «диспетчер».

Входной поток задач можно «раскладывать» по U, например, ч/з topic.
Для обмена U->T->UR достаточно и direct.
+1
кажется, вы слегка усложняете.

в случае с кафкой можно просто взять один топик (с фиксированным количеством партишенов) и в качестве ключа для партицирования использовать user_id.
каждый partition разгребать в один поток.
все задания этого юзера гарантированно будут там и обработаются последовательно.
думаю, что в 99% процентов случаев никаких проблем с перфомансом не будет.

либо как альтернатива — брать абсолютно любой брокер, в нем одну очередь, разбирать в любое количество потоков, а перед обработкой записи пробовать брать лок в каком-то стороннем месте (mysql SELECT GET_LOCK в базе где хранится юзер или в zookeper/consul). Конкретный юзер сейчас залочен? Сделали этому эвенту postpone и попробовали чуть позже (вопрос реализации postpone зависит уже от брокера)
0

Первый вариант с кафкой плох тем, что если вся нагрузка сосредоточилась на 1 партишене, нагрузка неравномерна. У меня мало нагрузки, чтобы такого не происходило.


Второй вариант с постпоном для меня не работает, так как задача должна уходить на обработку сразу, как только освобождается воркер. Непонятно, как э то организовать в механике postpone и не клинически большим пинанием задачи в очередь и из очереди.

0

Спасибо, звучит разумно. Этакий буферизующий воркер/диспетчер получается (если один "сложный").

0
А можно поподробнее про нулевую и ненулевую версию? Я думал, что есть вот просто AMPQ. Каждая последующая версия чуть лучше и с большим количеством фич чем предыдущая. А сейчас оказывается, что все совсем иначе…
0
«Поподробнее» — это на отдельный пост дел :-)

Если «на пальцах», то AMQP 1.0 — он не «лучше/хуже»… он просто *другой*. В том смысле, что это не *обновление* AMQP 0.10 (который, по понятным причинам, практически нигде не поддерживается) — это из серии «забудьте про топор — вот вам лопата».

Понятно, что понравилось это далеко не всем… и состав AMQP Working Group сильно — скажем так — изменился очень быстро.

0
И что теперь использовать (если мы говорим про новый проект)? Я так понял есть депрекейтед-стандарт который используется де-факто, и новый, который никому не понравился и который не поддерживается.

Бтв отдельный пост думаю был бы очень кстати. Можно от вас его ожидать? Лично я с удовольствием прочитал бы.
0
И что теперь использовать (если мы говорим про новый проект)?

Честно говоря — я не знаю. С одной стороны, «нулевая» серия — мертва. Т.е. она не развивается *централизовано". Основная причина, понятно, юридическая. И то, что кто-то таки пытается что-то «допиливать» — бьет по одной из самых ценных вещей «нулевой» серии — по интероперабельности. Плюс (точнее минус), нет абсолютно никаких гарантий в плане того, что его внезапно не перестанут вообще поддерживать с какого-то момента. Хотя, в таком состоянии он уже больше пяти лет :-) Альтернатив-то нет. Подвижки к «реанимации» были… но, тот же OpenAMQ «умер» очень быстро… причины, насколько я понимаю, те же. Т.е. проблема в «области права».

С другой стороны, 1.0 вообще не про интероперабельность «ни разу». И вы *сознательно* прибиваете себя к вендору, практически, намертво.

Я так понял есть депрекейтед-стандарт который используется де-факто, и новый, который никому не понравился и который не поддерживается.

Немножко не так… AMQP *был* стандартом, т.к. его рабочая группа состояла из «инженерных титанов». Которые разрабатывали именно *стандарт*… в инженерном смысле. Сейчас это далеко не так.

Ну и 1.0 не то, что «никому не понравился»… он не понравился тем самым «титанам». Но на их место пришла пара-тройка «вендоров». Которым возможность «привязать к себе» еще и этим очень даже понравилась.

Бтв отдельный пост думаю был бы очень кстати. Можно от вас его ожидать? Лично я с удовольствием прочитал бы.

Это сильно вряд ли… в ближайшее время — по крайней мере. И я — честно говоря — слабо представляю, что вы хотите узнать из этого поста. Писать про «чем лопата отличается от топора» желания у меня не много :-(
+1
И я — честно говоря — слабо представляю, что вы хотите узнать из этого поста. Писать про «чем лопата отличается от топора» желания у меня не много :-(

Да про все. Что за титаны, что за инженерные группы, почему новый стандарт это не стандарт, что за юридические нюансы… Для меня всё это новая информация, которую я нигде не встречал. Причем крайне важная. Потому что я вообще теперь перестал понимать, что мне использовать если я хочу очередь. Раньше я был уверен, что есть два живых конкурента, которые развиваются и делают интересные штуки, а теперь оказывается все совсем иначе…
+1
Что за титаны …

Из известных это, например, Cisco и Novell. Из менее известных — TWIST, например.

… почему новый стандарт это не стандарт…

По факту. «Нулевая» серия описывала, емнип, General Puprose Middleware *Standard*, а AMQP 1.0 всего лишь Advanced Message Queueing *Protocol* :-)

Если чуть серьезней, то спецификации «нулевой» серии описывала MOM целиком — т.е. от wire-layer, и до семантики обработки. И, собственно, *протокол* amqp — это, хоть и существенная, но лишь часть этих спецификаций.

Реализация этих спецификаций *гарантировала* полную интероперабельность узлов такой MOM. Что, в свою очередь, означало независимость от какого-либо конкретного вендора. Т.е. все как «у взрослых».

А спецификация AMQP 1.0 — формально — вообще не описывает МОМ. Она описывает некий транспортный уровень «в вакууме». Т.е. использовать это можно только «прикрутив» к какой-либо *уже существующей* МОМ — что, собственно, мы и наблюдаем.

Интероперабельность «узлов» *возможна* только на транспортном уровне — т.к. никакого другого в спецификации просто нет. Собственно, там и на транспортном уровне, много чего нет. Помнится, я — в свое время — словил много адреналина пытаясь выяснить *что именно* теперь связывает Connection. Это точно не инженеры писали.

Ну и понятно, что в таком виде оно нужно «не только лишь всем». И если лет пять назад в AMQP Working Group оставались Huawei и INETCO, то сейчас *инженерных* компаний там не осталось *совсем*. Что — лично для меня — весьма показательно.

… что за юридические нюансы…

Права на спецификации «нулевой» серии принадлежат, емнип, OASIS. И она как-то не горит желанием выпускать их в public domain :-) Т.е. вы не можете «просто так» взять спецификацию AMQP 0.10 и на её основе сделать свой AMQP 1.0 «with blackjack and hookers» (с)
+2

Спасибо за статью!


  1. Предположим, что у нас одна очередь и 10 получателей в RabbitMQ. Мы захотели ускорить обработку сообщений в 10 раз — вжух — увеличиваем количество получателей до 100, и сообщения обрабатываются быстрее. Насколько просто это сделать в Kafka, где у каждой партиции строго один получатель?
  2. В RabbitMQ, когда у каждой очереди много получателей, выход из строя одного из получателей не является катастрофой. А что происходит, если единственный получатель у партиции в Kafka выходит из строя? Кто обрабатывает "зависшие" в партиции данные?
+2
Насколько это может быть просто – зависит от начальных параметров очереди.

Единица параллелизма в Kafka – это partition, и если очередь создается со слишком маленьким количеством partitions, отмасштабироваться будет затруднительно: один получатель может обрабатывать несколько partitions, а вот одна partition читаться несколькими получателями – нет.
+1
Единица параллелизма в Kafka – это partition, и если очередь создается со слишком маленьким количеством partitions, отмасштабироваться будет затруднительно

Насколько я понял, перепилить partitions в продакшине — очень тяжело, почти нереально. Мне кажется, это весьма серьезное ограничение на масштабируемость.
0
Да. Поэтому окончательное количество партиций идеально подбирать по результатам нагрузочных испытаний, а не методом ленинского прищура.

Сам вендор (Confluent) предлагает максимально внимательно отнестись к этому вопросу и выпустил хорошее руководство по подбору параметра: How to choose the number of topics/partitions in a Kafka cluster
+1
Какбы вы там ни прищуривались, а жизнь не ограничивается одними стресс-тестами.
0
Единица параллелизма в Kafka – это partition

Стоит также отметить, что (наверное) все драйверы Кафки получают сообщения блоками (т.е. по N сообщений за раз) и некоторые из них предоставляют возможность параллельной обработки сообщений. Впрочем, это легко может быть реализовано и самостоятельно.
0

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

0
По второму вопросу, вроде как, в кафке все еще несколько проще. Новый/перезапущенный получатель вполне может знать место, на котором «сдох» предыдущий.
+1
Второй вопрос решается запуском нескольких консьюмеров с одинаковым group_id и эти консьюемеры будут как один логический консьюмер. Кафка будет сама балансить партиции между консьюмерами. Если два инстанса консьюмера с одинаковым group_id и две партиции, то каждый консьюмер будет обрабатывать свою партицию, если один консьюмер упадёт, то второй будет читать из двух партиций.
-1

Кажется у Вас опечатка в "Рис. 8. Три партиции и две группы по три получателей", там по логике должно быть "Рис. 8. Три партиции и три группы по два получателя"

+4
Главная боль рэббита — абсолютная неготовность к кластеризации. Причина — mnesa, которая готова устроить split brain по любому чиху. Например, если сделать ноде (erlang'овой) suspend, а потом resume (чтобы проэмулировать лаг), то мы получим split brain, который либо нерешаем, либо приводит к потери информации. И любые мысли «у нас нет таких лагов» натыкаются на вопрос: у вас нет, а у вашего компьютера? Interrupt storm, баг в acpi, thermal throttling, баги в ядре — и всё, процесс радостно считает, что он один живой, а все пиры сдохли. А пиры считают так же.

В standalone режиме он вполне хорош, если не считать постоянного wtf из-за изобилия эрланговых глупостей (двустрочный логгинг, переключение между beamp/beam.smp в зависимости от числа ядер и т.д.).
0
Они могут направить несколько типов событий из нескольких топиков в свою очередь.… Это просто невозможно с помощью системы обмена сообщениями на основе журнала, такой как Kafka, поскольку журналы являются общими ресурсами.

В кафке консумер может читать одновременно из нескольких топиков, не вижу принципиальной разницы.
0

Я правильно понимаю, что обе эти системы предназначены для одностороннего обмена информацией? То есть источник сообщений может передать информацию потребителю, а потребитель не может вернуть источнику результат.

0
в rabbitmq есть механизм rpc — можно в сообщении указать «положи мне ответ в такую-то очередь»
0
Спасибо за перевод!
Ничего не сказано про масштабируемость кластера. Это одна из проблем Кафки. Ее невозможно масштабировать под нагрузкой, тк дополнительная репликация на новые брокеры в кластере вызовет повышенное потребление ресурсов и станет еще хуже.
То есть кластер лучше держать несколько over provisioned.
А что с RabbitMQ с масштабированием под нагрузкой?
0

Просто нужно расширяться заранее, а не когда жареный петух клюнет.


А кролик вообще в контексте одной очереди не масштабируем — клиенты про кластер ничего не знают. Нужно партиционировать со стороны приложения вручную как то

0

Может кто знает для RabbitMQ есть какая-нибудь система мониторинга типа Kibana? Чтобы json логи онлайн можно было удобно фильтровать и разворачивать для просмотра?

Only those users with full accounts are able to leave comments. , please.