Comments 41
это серия из 5-и статей которая сравнивает именно кролика и кафку, но мы посмотрим как можно вписать
Что касается самой статьи, то практически всё, что в ней сказано про RabbitMQ (за исключением, возможно, «масштабируемости»), собственно, к самому «кролику» имеет весьма опосредованное отношение. Оно всё про AMQP «нулевой» серии.
А поскольку, авторы, судя по всему, в AMQP разбираются «ниочинь» (это я про оригинал), то — лично у меня — возникает «смешенное чувство» от «рассуждений» про «использует push», про «конкурирующих получателей» и т.п.
… но в java приложениях его используют через JMS клиентов и в этом случае решения функционально совместимы.
Вообще-то нет. Т.к. на «движок» AMQP 0.9, 0.10 «ложится» практически любой messaging — в том числе, и AMQP 1.0. А вот наоборот — уже нет. Т.е. про все «плюшки» маршрутизации «на брокере» уже можно будет забыть.
Либо у нас сильно разное понимание «функциональной совместимости».
За свою практику приходилось работать с 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. Так что видимо у нас действительно разное понимание функциональности, совместимости.
Одно дополнение.
Когда вы имеете дело с ИИОТ то важным требованием является возможно апгрейда микросервисов с 0 остановкой (Blue/Green/Canary).
Использование потоковых инструментов типа кафки или кинесиса позволяет деплоить с существенно более простой архитектурой, поскольку поток всегда можно пере-проиграть снова в случае откатов.
Для многих «edge» сервисов мы используем стримы именно по этому поводу.
Извините за возможный офтопик. Мне нужна очередь для выполнения определенных вычислений (каждая задача относится к конкретному пользователю). Но таким образом, чтобы задачи, относящиеся к одному пользователю, не передавались на обработку одновременно. Есть ли возможность сделать это на какой-то "стандартной" очереди? Или придется делать свое решение? Кафка, судя по описанию, умеет группировать события по признаку, но мне не нравится, что может получиться ситуация, когда один воркер ничего не делает, а второй перегружен задачами.
Логика работы «вычислителя» примерно следующая:
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.
в случае с кафкой можно просто взять один топик (с фиксированным количеством партишенов) и в качестве ключа для партицирования использовать user_id.
каждый partition разгребать в один поток.
все задания этого юзера гарантированно будут там и обработаются последовательно.
думаю, что в 99% процентов случаев никаких проблем с перфомансом не будет.
либо как альтернатива — брать абсолютно любой брокер, в нем одну очередь, разбирать в любое количество потоков, а перед обработкой записи пробовать брать лок в каком-то стороннем месте (mysql SELECT GET_LOCK в базе где хранится юзер или в zookeper/consul). Конкретный юзер сейчас залочен? Сделали этому эвенту postpone и попробовали чуть позже (вопрос реализации postpone зависит уже от брокера)
Первый вариант с кафкой плох тем, что если вся нагрузка сосредоточилась на 1 партишене, нагрузка неравномерна. У меня мало нагрузки, чтобы такого не происходило.
Второй вариант с постпоном для меня не работает, так как задача должна уходить на обработку сразу, как только освобождается воркер. Непонятно, как э то организовать в механике postpone и не клинически большим пинанием задачи в очередь и из очереди.
Спасибо, звучит разумно. Этакий буферизующий воркер/диспетчер получается (если один "сложный").
Если «на пальцах», то AMQP 1.0 — он не «лучше/хуже»… он просто *другой*. В том смысле, что это не *обновление* AMQP 0.10 (который, по понятным причинам, практически нигде не поддерживается) — это из серии «забудьте про топор — вот вам лопата».
Понятно, что понравилось это далеко не всем… и состав AMQP Working Group сильно — скажем так — изменился очень быстро.
Бтв отдельный пост думаю был бы очень кстати. Можно от вас его ожидать? Лично я с удовольствием прочитал бы.
И что теперь использовать (если мы говорим про новый проект)?
Честно говоря — я не знаю. С одной стороны, «нулевая» серия — мертва. Т.е. она не развивается *централизовано". Основная причина, понятно, юридическая. И то, что кто-то таки пытается что-то «допиливать» — бьет по одной из самых ценных вещей «нулевой» серии — по интероперабельности. Плюс (точнее минус), нет абсолютно никаких гарантий в плане того, что его внезапно не перестанут вообще поддерживать с какого-то момента. Хотя, в таком состоянии он уже больше пяти лет :-) Альтернатив-то нет. Подвижки к «реанимации» были… но, тот же OpenAMQ «умер» очень быстро… причины, насколько я понимаю, те же. Т.е. проблема в «области права».
С другой стороны, 1.0 вообще не про интероперабельность «ни разу». И вы *сознательно* прибиваете себя к вендору, практически, намертво.
Я так понял есть депрекейтед-стандарт который используется де-факто, и новый, который никому не понравился и который не поддерживается.
Немножко не так… AMQP *был* стандартом, т.к. его рабочая группа состояла из «инженерных титанов». Которые разрабатывали именно *стандарт*… в инженерном смысле. Сейчас это далеко не так.
Ну и 1.0 не то, что «никому не понравился»… он не понравился тем самым «титанам». Но на их место пришла пара-тройка «вендоров». Которым возможность «привязать к себе» еще и этим очень даже понравилась.
Бтв отдельный пост думаю был бы очень кстати. Можно от вас его ожидать? Лично я с удовольствием прочитал бы.
Это сильно вряд ли… в ближайшее время — по крайней мере. И я — честно говоря — слабо представляю, что вы хотите узнать из этого поста. Писать про «чем лопата отличается от топора» желания у меня не много :-(
И я — честно говоря — слабо представляю, что вы хотите узнать из этого поста. Писать про «чем лопата отличается от топора» желания у меня не много :-(
Да про все. Что за титаны, что за инженерные группы, почему новый стандарт это не стандарт, что за юридические нюансы… Для меня всё это новая информация, которую я нигде не встречал. Причем крайне важная. Потому что я вообще теперь перестал понимать, что мне использовать если я хочу очередь. Раньше я был уверен, что есть два живых конкурента, которые развиваются и делают интересные штуки, а теперь оказывается все совсем иначе…
Что за титаны …
Из известных это, например, 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» (с)
Спасибо за статью!
- Предположим, что у нас одна очередь и 10 получателей в RabbitMQ. Мы захотели ускорить обработку сообщений в 10 раз — вжух — увеличиваем количество получателей до 100, и сообщения обрабатываются быстрее. Насколько просто это сделать в Kafka, где у каждой партиции строго один получатель?
- В RabbitMQ, когда у каждой очереди много получателей, выход из строя одного из получателей не является катастрофой. А что происходит, если единственный получатель у партиции в Kafka выходит из строя? Кто обрабатывает "зависшие" в партиции данные?
Единица параллелизма в Kafka – это partition, и если очередь создается со слишком маленьким количеством partitions, отмасштабироваться будет затруднительно: один получатель может обрабатывать несколько partitions, а вот одна partition читаться несколькими получателями – нет.
Единица параллелизма в Kafka – это partition, и если очередь создается со слишком маленьким количеством partitions, отмасштабироваться будет затруднительно
Насколько я понял, перепилить partitions в продакшине — очень тяжело, почти нереально. Мне кажется, это весьма серьезное ограничение на масштабируемость.
Сам вендор (Confluent) предлагает максимально внимательно отнестись к этому вопросу и выпустил хорошее руководство по подбору параметра: How to choose the number of topics/partitions in a Kafka cluster
Единица параллелизма в Kafka – это partition
Стоит также отметить, что (наверное) все драйверы Кафки получают сообщения блоками (т.е. по N сообщений за раз) и некоторые из них предоставляют возможность параллельной обработки сообщений. Впрочем, это легко может быть реализовано и самостоятельно.
Да нет вроде особых проблем добавить партиции под нагрузкой. Уменьшить их колво нельзя, это да.
Кажется у Вас опечатка в "Рис. 8. Три партиции и две группы по три получателей", там по логике должно быть "Рис. 8. Три партиции и три группы по два получателя"
В standalone режиме он вполне хорош, если не считать постоянного wtf из-за изобилия эрланговых глупостей (двустрочный логгинг, переключение между beamp/beam.smp в зависимости от числа ядер и т.д.).
Они могут направить несколько типов событий из нескольких топиков в свою очередь.… Это просто невозможно с помощью системы обмена сообщениями на основе журнала, такой как Kafka, поскольку журналы являются общими ресурсами.
В кафке консумер может читать одновременно из нескольких топиков, не вижу принципиальной разницы.
Я правильно понимаю, что обе эти системы предназначены для одностороннего обмена информацией? То есть источник сообщений может передать информацию потребителю, а потребитель не может вернуть источнику результат.
Ничего не сказано про масштабируемость кластера. Это одна из проблем Кафки. Ее невозможно масштабировать под нагрузкой, тк дополнительная репликация на новые брокеры в кластере вызовет повышенное потребление ресурсов и станет еще хуже.
То есть кластер лучше держать несколько over provisioned.
А что с RabbitMQ с масштабированием под нагрузкой?
Может кто знает для RabbitMQ есть какая-нибудь система мониторинга типа Kibana? Чтобы json логи онлайн можно было удобно фильтровать и разворачивать для просмотра?
RabbitMQ против Kafka: два разных подхода к обмену сообщениями