Чем различаются Kafka и RabbitMQ: простыми словами

Kate

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

Какие бывают виды общения?​

Давайте разберёмся, какие виды общения нас окружают. Самый распространённый вариант — любой диалог. Кто-то N обращается к кому-то Y и высказывает ему мнение, ждёт ответа или обратную связь.

Пример, общение по телефону:

39cb5560643aa0e4c9733e6c8c2747ff.png

Или всё то же самое, только N, транслируя сообщение Y, не ждёт от него ответа. Да-да, бывают такие люди, которые только привыкли высказывать собственное мнение. Также, кстати, работают рекламные рассылки или push-уведомления на телефоне.

Работа системы оповещения:

884ca90934f39a7935e0c8c2750b029e.png

Есть варианты общения не напрямую, а через посредника. Например, N просит X запомнить сообщение и передать всем его друзьям. При этом N не знает, кто входит в круг друзей X. X передаёт сообщение всем друзьям — C, D, E.

Хороший пример — это работа мессенджера. Отправитель публикует сообщения в определённые группы, пользователи подписываются и читают их.

7c3c8b57c45c52727b0ef8efcc39036f.png

В другом похожем варианте N записывает сообщение на карточке и отдаёт X. X складывает карточки в специальный ящик. Те у кого есть доступ, по очереди заглядывают в ящик и забирают каждый по одному сообщению. Одно сообщение, один получатель.

ca6b6a9dc08cc357622380ae57e6a4d6.png

Паттерны обмена информации​

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

Существуют разные способы обмена, из классификации которых определяются паттерны. Выше в упрощённом виде были перечислены четыре основных паттерна общения, которые так же присущи программам:

  • Request-Response (Запрос-Ответ);
  • One-Way (Односторонний) или Fire and Forget (Отправил и забыл);
  • Publish-Subscribe (Публикация-Подписка) или сокращённо Pub-Sub;
  • Point-to-Point (Точка-Точка).
В интернете Request-Response — это работа HTTP: клиент выполняет запрос на сервер, ждёт и получает ответ. One-Way, когда приложение по сети отправляет UDP (User Datagram Protocol) пакет на сервер без ожидания ответа. Последние два варианта связаны с брокерами сообщений, но о них чуть позже.

Часто в рамках взаимодействия приложения используют паттерн Request-Response. Программы общаются напрямую синхронно друг с другом. У такого взаимодействия есть особенности:

  • отправителю нужно знать адрес получателя;
  • получатель должен быть доступен в момент вызова;
  • из-за сбоя отправитель может никогда не дождаться ответа;
  • отправитель блокируется в ожидании ответа.
C развитием технологий, микросервисной архитектуры, IoT и общим ростом количество программ, синхронный подход общения приложений перестал удовлетворять. Потребовались новые решения.

В паттернах Pub-Sub и Point-to-Point происходит асинхронное общение через посредника. При реализации таких паттернов у программ появляются возможности:

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

Так кто такие брокеры?​

Итак, на прошлых картинках под буквой X прятался брокер сообщений (Message Broker).

c515b3ac071692e4a61e6875d06b99fd.png

Брокер сообщений — это программная система полностью или частично реализующая паттерны Pub-Sub и Point-to-Point. Взаимодействие программ через брокер упрощает процесс разработки. Нет необходимости в каждом сервисе реализовывать механизмы доставки, маршрутизации, хранения сообщений — всем этим занимается «посредник». Общение через «посредника» помогает навести порядок и внести ясность в потоки данных, а значит, упростить разработку и снизить вероятность появление ошибок.

6c7110fd9ad1a0bff00c0d4b83b86547.png

Использование брокера оправдано, если:

  • существуют задачи, выполнение которых требует много времени и ресурсов;
  • не нужен немедленный результат;
  • необходима координация работы большого количества сервисов (событийная модель общения);
  • требуется повысить масштабируемость и отказоустойчивость системы.

Гарантия доставки​

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

  • At most once (Не более одного раза)
    Самый простой вариант — отправка в стиле Fire and Forget (Отправил и забыл). Большая часть сообщений доходит до получателя, но часть теряется из-за сбоев.
2056ba34a3f9e34d67a63fddfb82220b.png

  • At least once (Хотя бы один раз)
    Чтобы все данные достигли цели, могут предприниматься повторные отправки. Хотя бы одна попытка будет успешной. В таком случае сообщения не теряются, но могут дублироваться.
    Обычно реализуется через механизм подтверждений (ACK, acknowledgment). Сообщение повторяется, если не получено подтверждение о доставке. Возможны дубли, если подтверждение потерялось или не было отправлено из-за сбоя.
9b91bacb210aae9dccc80979c785fb09.png

  • Exactly once (Строго один раз)
    Самый труднодостижимый вариант —максимальная гарантия доставки. Сообщения никогда не теряются и не дублируются, каждое доставляется ровно один раз.
ab22751afc53db36474d1058f147bf8e.png

Очередь и Топик​

Брокер, реализующий шаблон Point-to-Point, ассоциируется с термином Queue (Очередь). Сообщения отправителя попадают в очередь, получатель извлекает сообщения из очереди. После извлечения сообщение становится больше никому не доступными. Данные в очереди хранятся, пока они не будут прочитаны или не истечёт срок их действия.

В Pub-Sub ассоциируется с темой, топиком (Topic). Сообщения попадают в топик. Система распределяет каждое сообщение между всеми подписчиками топика (Broadcast, вещание). Сообщения могут храниться в топике, до тех пор, пока это необходимо для распространения данных между всеми подписчиками.

Разнообразие брокеров в природе​

Существует множество программных реализаций брокеров сообщений. Одни из самых известные:

Каждая из реализаций может отличаться по характеристикам:

  • масштабируемость, пропускная способность;
  • отказоустойчивость, возможность восстановления данных в результате сбоя;
  • кластеризация;
  • поддержка моделей Pub-Sub и Point-to-Point;
  • гарантия доставки сообщений;
  • упорядоченная доставка сообщений;
  • контроль доступа;
  • открытость кода;
  • поддерживаемые платформы.
Например, в программных решениях «Иннотех» активно используются, ставшие де-факто стандартом, брокеры сообщений Kafka и RabbitMQ. У этих брокеров есть определённые отличия и особенности работы. Разберём их в качестве примера для понимания специфики принципов работы.

«Умный брокер, тупой потребитель»​

RabbitMQ традиционный брокер сообщений с открытым исходным кодом, работающий как автономно, так и в составе кластера. Поддерживает обе модели Pub-Sub и Point-to-Point, протоколы AMQP, MQTT, STOMP и другие. Реализованы гарантии доставки сообщений At most once и At least once.

В случае At most once получается большая пропускная способность, так как данные обрабатываются в быстрой оперативной памяти. At least once надёжный в плане доставки, но менее скоростной в плане передачи данных вариант, потому что используется механизм подтверждений и запись на диск.

В упрощённом виде принципы работы RabbitMQ можно представить так: приложение-отправитель (Publisher) публикует сообщения в брокер, ссылаясь на его внутреннюю сущность Exchange (Обменник). Обменник в зависимости от типа и настроек перенаправляет сообщения в одну или более связанных с ним очередей (Queue). Приложения-подписчики (Consumer) держат постоянное TCP соединение с RabbitMQ и ждут сообщения из заданной очереди. Брокер отправляет (push), распределяет сообщения между подписчиками. Если у очереди несколько подписчиков, сообщения между ними распределяются равномерно. Если сообщение успешно обработано подписчиком, оно удаляется из очереди.

RabbitMQ может слать подтверждение отправителю после того, как сохранил его сообщение. Или ждать подтверждения от получателя об успешной обработке взятого из очереди сообщения.

d851092c98d092e9d80091912741142b.png

Принцип «Умный брокер, тупой потребитель» по отношению к RabbitMQ означает, что брокер берёт на себя много дополнительных действий. Например, следит за прочитанными сообщениями и удаляет их из очереди. Или сам организует процесс распределения сообщений между подписчиками

«Тупой брокер, умный потребитель»​

Apache Kafka программный Pub-Sub брокер с открытым исходным кодом. Помимо гарантий доставки At most once и At least once, поддерживает Exactly once (Строго один раз). Обычно используется в больших проектах, так как обладает большой пропускной способностью и отказоустойчивостью, превосходит по данным характеристикам RabbitMQ и многие другие брокеры. При этом имеет высокий порог вхождения, требователен к ресурсам.

Kafka можно представить, как распределённый, реплицируемый лог коммитов. Распределённый, так как он разворачивается в виде кластера нод (под управлением Apache Zookeeper). Реплицируемый, потому что все данные синхронизируются между нодами. Лог, входящие сообщения последовательно добавляются в журнал и остаются там неизменными, не удаляются при чтении, как это происходит в RabbitMQ.

dfabbc3ef8cfaccbf2c99fcaceca0abb.png

В Kafka отсутствует понятие очереди (Queue), приложения пишут или читают сообщения из партиционированных топиков (Topic). Если просто, то принцип работы такой: приложение-продюсер (Producer) отправляет сообщение в топик брокера, которое записывается в конец одной из его партиций (Partition). По умолчанию для распределения сообщений между партициями топика используется алгоритм Round-Robin. Отправитель может влиять на выбор партиции, передавая вместе с сообщением специальный ключ (Message Key).

Приложения-подписчики (Consumer) читают, вытягивают (pull) сообщения из заданного топика. Для каждого подписчика Kafka запоминает указатель на последнее прочитанное им сообщение (offset). Если приложение падает, то восстановившись может продолжать чтение с прежнего места или перемотать (rewind) offset в прошлое и прочитать данные повторно.

Для Kafka принцип «Тупой брокер, умный потребитель» означает, что, в отличие от RabbitMQ, он не занимается контролем и распределением сообщений. Потребители сами опрашивают брокер и решают, какие сообщения им читать, брокер только хранит данные.

fbda121ab3fd238ab1ea4fba06b189ff.png

Количество партиций в топике зависит от количества его конкурирующих подписчиков. Одно приложение не может читать данные из одной партиции в несколько потоков. Параллелизм достигается за счёт увеличения количества партиций, для каждого потока своя.

В RabbitMQ такой проблемы не существует. Брокер проталкивает (push) сообщения подписчикам и поэтому может сам балансировать, распределять данные между подписчиками очереди. С другой стороны, Push-механизм (Одно сообщение за один раз) менее продуктивный по сравнению с Pull в Kafka.

Выбирая между Kafka и RabbitMQ​

На самом деле, категорично сравнивать брокеры сообщений очень сложно. У всех существуют свои задачи и области применения. В случае с Apache Kafka и RabbitMQ это немного разный уровень, где лучшего не существует.

Kafka используется для обработки больших объёмов данных, сотен тысяч сообщений в секунду, которые подолгу хранятся на диске и много раз читаются сотнями или даже тысячами подписчиков. Kafka — это легко масштабируемая система, обладающая повышенной отказоустойчивостью, что очень важно в крупных проектах.

RabbitMQ более простой в установке и настройке, успешно справляется с асинхронным обменом данными в микросервисной архитектуре. Не требует дополнительных компонентов и затрат на дисковые ресурсы, так как все сообщения после чтения из очереди удаляются. По сравнению с Kafka обладает большими возможностями по настройке шаблонов обмена сообщениями. Отличный выбор, если нет завышенных требований к отказоустойчивости и пропускной способности.


 
Сверху