Всем привет, 

Команда devhands.io сделала с Владимиром Перепелицей мини-интервью, посвященное сравнению наиболее популярных решений в области очередей и брокеров сообщений — Kafka, RabbitMQ, NATS.

Владимир — эксперт по большим проектам, очередям и Tarantool, Solution Architect в Exness, создатель S3 в VK Cloud, регулярный спикер и член ПК конференций Highload.

Хотим поделиться с вами текстовой расшифровкой интервью.

Q: Владимир, в 4-й Кафке завезли более «классические» очереди. А чем топики с партициями не очередь? В чём отличие «классической» очереди от топика с партициями?

Топик в кафке по своей природе — это распределённый лог, а не очередь. 

Основные отличия:

  1. В кафке топик сохраняет сообщения в виде неизменяемого, упорядоченного по времени лога. Сообщения не удаляются из лога при доставке. В классической очереди сообщение после успешной обработки удаляется — доставляется ровно один раз одному из потребителей. 

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

  3. Гранулярность «ack». В Кафке стандартный способ подтверждения обработки — это коммит смещения (оффсета). Коммит подтверждает разом все сообщения до этого оффсета. Подтверждать обработку индивидуальных сообщений нельзя. В очередях обычно подтверждение происходит индивидуально по сообщению, позволяя точно контролировать повторную доставку.

Q: Что поменялось с введением Kafka Queues, как они работают?

С выходом Kafka 4.0 по KIP-932 появились Share Groups (разделяемые группы) — псевдо-очереди поверх топиков. Под капотом всё остаётся так же, но изменяется модель потребления:

  1. Share  Groups подразумевают кооперативное потребление без жёсткого назначения партиций. Несколько потребителей в одной группе могут одновременно читать из одной и той же партиции, кооперируясь между собой по блокам сообщений.

  2. Индивидуальный ack. Сообщения повторно доставляются потребителям до тех пор, пока не будет подтверждена их обработка.

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

Q: Как масштабируются Kafka Queues?

Если мы говорим про сам брокер и хранение и обработку очереди, то как и раньше очередь масштабируется партициями, которые в свою очередь распределяются по брокерам. Больше партиций — больше брокеров — больше пропускная способность.

Но теперь share groups снимает важное ограничение на количество потребителей. Теперь, используя этот механизм можно запускать любое количество потребителей, необходимое для обработки потока. Кафка сама разобьёт поток на блоки и раздаст их активным экземплярам.

Q: Три наиболее популярных решения в мире очередей - это  Kafka, Rabbit и NATS. В чём фундаментальные отличия между ними? Кого кем можно заменять и в каких случаях?

Окей, ну давай сначала кратко, кто есть кто:

Kаfka

  • Реплицированный шардированный лог сообщений.

  • Бесконечное горизонтальное масштабирование с помощью партиций.

  • Минимальный набор примитивов (pub/sub log).

  • Кластера в пределах одного «близкого» дата-центра или облачной зоны.

Rabbit

  • Классическая "очередь".

  • Традиционный брокер с протоколом AMQP.

  • Богатой функциональностью «из коробки».

  • Не масштабируется горизонтально.

NATS

  • Мультипарадигменная распределённая доставка сообщений (pub/sub, request/reply, key/value, streams).

  • JetStream: надёжный механизм потоковой обработки.

  • Кластеризация от одного узла до глобальных суперкластеров с гео-маршрутизацией.

  • Легковесный и современный.

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

Теперь посмотрим на детали сравнений подробнее, и начнем с активно набирающего популярность NATS.

NATS vs (Kafka | Rabbit)

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

Это делает его победителем по следующим категориям критериев:

  • Getting Started, Удобство локальной разработки. Запуск в docker. Rabbit сложнее запустить, Kafka требует большего количества компонент и настроек.

  • End-to-end latency. NATS доставляет сообщение с sub-millisecond latency за счёт использования golang и in-memory подходов. Rabbit обычно немного отстаёт, у кафки латенси может быть выше на порядок.

  • Поиск и фильтрация сообщений на сервере. NATS JetStream создавался с оглядкой на вещи, которых не хватало в Kafka Streams и с учётом недостатков AMQP по поиску сообщений в брокере.

  • Простота администрирования. Использование golang подходов делает NATS намного более простым в диагностике и настройке в промышленной эксплуатации. Rabbit c его erlang на порядки сложнее при проблемах. Kafka использует экосистему Java и в целом занимает среднюю позицию за счёт широкого распространения.

  • Geo-репликация и глобальная доставка. Дизайн NATS изначально предусматривал глобальную кластеризацию и суперкластера. У Kafka хороший горизонтальный кластер и инструменты для межкластерной репликации.

Kafka vs (NATS | Rabbit)

Создавалась с нуля под задачу обработки больших потоков данных и горизонтального масштабирования.

Прочно доминирует по следующим критериям:

  • Горизонтальное масштабирование, Пропускная способность, Репликация и отказоустойчивость. Эти свойства были основными целями, которые стояли перед создателями Kafka на стадии дизайна, поэтому не удивительно, что Kafka бьёт всех по этим показателям. Весьма удачная архитектура партиционированного реплицированного лога с кворумом позволяет хорошо одновременно сочетать данные критерии.

  • Stream processing. Потоковая обработка данных в этом формате получила максимальное распространение именно благодаря Kafka. В NATS данная функциональность была добавлена в виде JetStream, Rabbit добавил потоковую обработку как отдельную функцию, но её возможности не дотягивают до возможностей Kafka.

  • Конфигурирование и тюнинг. Kafka, в отличие от NATS и Rabbit обладает значительным набором параметров, позволяющих выполнить тонкую настройку поведения сервера и кластера.

  • Зрелость проекта. Доки и обучение. Сообщество и поддержка. Экосистема и интеграции. С момента своего появления на IT-ландшафте Kafka быстро заняла нишу обработки данных и впоследствии расширила эту нишу до значительного сектора. Как результат — рост сообщества и появление большого количества материалов. За несколько лет Kafka стала фактически стандартом де-факто для сценария потоковой передачи данных, что спровоцировало интеграцию с большим количеством существующих инструментов и появление новых. RabbitMQ является достаточно старым и стандартным инструментом. Он накопил сообщество и информацию, но в последние годы теряет свою популярность. NATS достаточно новый инструмент и на текущий момент находится в фазе роста популярности.

Rabbit vs (Kafka | NATS)

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

Как протокол, так и его реализация не закладывали в дизайн распределённые системы и горизонтальное масштабирование и это сказалось на итоговых свойствах: будучи весьма производительным и функциональным "монолитом" RabbitMQ имеет пределы пропускной способности. Будучи реализован на Erlang обладает малой базой коммитеров.

Исходя из всего, его сильной стороной являются поддержка различных протоколов, поддержка "очередей", различные механизмы подтверждения доставки.

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

Более современные инструменты, такие как NATS и Kafka создавались под решение специфичных задач и в том числе с целью решения проблем классических монолитных брокеров очередей под распределённые и масштабируемые системы. Kafka никогда не ставила перед собой цели стать классическим брокером очередей, а NATS в своём дизайне заимствовал только некоторые идеи и подходы, которые не противоречили распределённой архитектуре.

ИТОГО:

Ориентируясь на эти критерии можно оценить применимость и заменимость того или иного инструмента под задачу

  • RabbitMQ если нужна классическая очередь

  • NATS если нужны легковесность, быстрота и простота

  • Apache Kafka если требуется зрелый промышленный инструмент для больших потоков данных с богатой экосистемой

Комментарии (0)