Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Kafka против RabbitMQ: как выбрать брокер

Kafka или RabbitMQ: честное сравнение под задачу

Kafka и RabbitMQ по критериям: модель доставки, ретраи и DLQ, порядок, масштаб и эксплуатация — таблица, сценарии выбора и гибридные схемы.

Прямой ответ

Фундаментальное различие — модель данных: Kafka — распределённый лог (сообщения хранятся в партициях, потребители читают с offset'а — событие можно перечитать — «история» — Kafka-основы), RabbitMQ — очередь (broker push'ит сообщения потребителям, обработанное удаляется — «прочитал — исчезло» — классическая очередь — очереди-семантика); из этого следуют все остальные различия; критерии выбора: (1) ретраи и dead letter — RabbitMQ сильнее «из коробки»: per-message TTL, dead letter exchange (DLX — «не обработано → в DLQ» — декларативно), per-queue retry-политики, delayed message plugin — «взять и настроить» — вебхук-аналогия; Kafka — ретраи/DLQ — на потребителе (библиотека/свой код — retry-топик + DLQ-топик — consumer-паттерны — гибче, но руками); (2) порядок — Kafka: строго внутри партиции (ключ → партиция — consumer groups), RabbitMQ: в очереди FIFO, но конкурентные потребители + ретраи ломают порядок (переспорядочивание — «порядок в RabbitMQ» — хрупче); (3) масштаб пропускной способности — Kafka: сотни тысяч–миллионы msg/s (секвенционный диск-IO, батчинг, партиционность — ёмкость), RabbitMQ: десятки тысяч msg/s (одна очередь — один поток — масштаб через шардинг очередей — меньше потолок); (4) перечитывание/воспроизведение — Kafka: да (сброс offset'ов — репроцессинг истории — consumer-операции — «заново обработать за неделю»), RabbitMQ: нет (обработанное удалено — история не хранится — «перечитать» — невозможно без внешнего хранилища); (5) маршрутизация — RabbitMQ: богатая (exchange-типы: direct/topic/fanout/headers — гибкая маршрутизация — «событие → несколько очередей по правилам» — event-driven), Kafka: проще (топик → партиции по ключу — маршрутизация на потребителе — fanout через несколько consumer groups); (6) задержка — RabbitMQ: миллисекунды (push-модель — низкая латентность для «обработать сразу»), Kafka: миллисекунды-десятки (batch-ориентирован — латентность чуть выше — но для потоков приемлемо); (7) Эксплуатация — RabbitMQ: Erlang-стек (один узел/кластер — проще старт — docker-compose), Kafka: JVM + (KRaft вместо ZooKeeper в 3.x — проще — раньше — ZooKeeper-зависимость — тяжелее — Kafka-эволюция); сценарии выбора: событийные потоки/аналитика/event sourcing/CDC — Kafka (лог, воспроизведение, масштаб — event sourcing), очереди задач/ретраи/DLQ/сложная маршрутизация/RPC — RabbitMQ (гибкость очередей, низкая латентность — Celery-контекст), высокий throughput (логи/метрики/телеметрия) — Kafka (ёмкость), низкий throughput со сложной логикой доставки — RabbitMQ; гибрид — частая реальность (Kafka для потоков/событий, RabbitMQ для задач/ретраев — разные роли — дизайн).

Сравнение по критериям

Таблица (сжато): Модель — Kafka: append-only лог (хранение retention — перечитываемо), RabbitMQ: очередь (push, удаление после ack — очереди); Порядок — Kafka: строгий в партиции, RabbitMQ: FIFO в очереди (но ретраи/конкуренты ломают — consumer); Пропускная способность — Kafka: очень высокая (100k–1M+ msg/s), RabbitMQ: умеренная (10k–50k msg/s на очередь); Латентность — оба низкая (RabbitMQ чуть ниже для point-to-point); Ретраи/DLQ — RabbitMQ: встроенные (DLX/TTL/delayed — декларативно — вебхук), Kafka: на потребителе (retry/DLQ-топики — код); Перечитывание — Kafka: да (offset reset), RabbitMQ: нет; Маршрутизация — RabbitMQ: exchanges (богатая), Kafka: ключ-партиционирование (проще); Хранение — Kafka: дни/недели (retention — история), RabbitMQ: до обработки (не архив); Fan-out — Kafka: consumer groups (каждый читает всё), RabbitMQ: fanout exchange; Кластеризация — Kafka: партиции+репликация (failover — аналогия), RabbitMQ: quorum queues (Raft-репликация — консенсус); Экосистема — Kafka: Kafka Streams/Connect/ksqlDB (потоковая обработка), RabbitMQ: плагины/протоколы (AMQP/MQTT/STOMP); Эксплуатационная сложность — RabbitMQ: ниже на старте (один узел), Kafka: выше (партиции/KRaft/мониторинг — но масштабируется линейно — ёмкость); Выбор по задаче: потоки/события/аналитика/воспроизведение → Kafka; задачи/ретраи/сложная маршрутизация/низкая латентность → RabbitMQ; event-driven-контекст — модель диктует выбор.

Практический сценарий: два брокера в одной системе

Контекст: SaaS-платформа (заказы/платежи/уведомления/аналитика), стартовый стек — RabbitMQ для всего; симптомы роста: аналитика «перечитать события за месяц» невозможна (RabbitMQ не хранит обработанное — очереди), поток телеметрии 50k msg/s — RabbitMQ-очередь захлёбывается (backpressure), event sourcing для аудита платежей требует историю (event sourcing); решение — гибрид (не миграция «всё на Kafka», а разделение по ролям — дизайн): (1) Kafka — для событийных потоков: доменные события (OrderPlaced/PaymentProcessed — event-carried state — event-driven), телеметрия/метрики (высокий throughput — партиционность — ёмкость), event sourcing аудита (лог событий — воспроизведение — event sourcing), CDC (Debezium → Kafka — логическая репликация — изменения БД как поток); (2) RabbitMQ — для задач и ретраев: фоновые задачи (Celery-подобные — ретраи/DLQ из коробки — Celery), уведомления с ретраями (delayed message — «отправить через 5 минут» — DLX — вебхук), RPC-паттерны (request/reply — низкая латентность — gRPC-альтернатива), сложная маршрутизация (topic exchange — «событие → несколько очередей по правилам» — event-driven); (3) мост (Kafka → RabbitMQ для задач: consumer читает Kafka-событие, публикует задачу в RabbitMQ — паттерн — разные сильные стороны — интеграция); (4) outbox для надёжности (события в Kafka через outbox — saga — атомарность БД+событие — event-driven); итоги: аналитика перечитывает историю (Kafka retention 30 дней — consumer-reset), телеметрия 50k msg/s держится (партиционность — ёмкость), задачи с ретраями работают (RabbitMQ DLX — Celery), event sourcing аудита есть (Kafka-лог — event sourcing); цена гибрида: два брокера эксплуатировать (две системы мониторинга/обновлений — зависимости — операционная нагрузка — ёмкость), команда знает оба (обучение — техдолг); вывод: «Kafka или RabbitMQ» — часто «и то, и другое» — разные инструменты для разных задач — гибриды — реальность крупных систем, не компромисс — микросервисы — выбор по модели данных, не по моде — ADR.

FAQ

Можно ли использовать Kafka как очередь задач (вместо RabbitMQ)? Да, но с оговорками: Kafka-паттерн для задач — retry-топики + DLQ-топик (обработчик при ошибке публикует в retry-топик с задержкой через scheduled-топик/внешний delay — после N ретраев → DLQ — consumer-паттерны — руками, RabbitMQ DLX делает декларативно — вебхук); минусы Kafka-как-очереди: нет встроенного per-message ACK (offset-коммит — групповой — consumer — «одна задача упала» — обработка offset сложнее), нет native delayed delivery (delayed message plugin RabbitMQ — из коробки), порядок/ретраи конфликтуют (ретрай задачи ломает порядок партиции — consumer); когда Kafka-задачи ок: высокий throughput задач (100k+ msg/s — RabbitMQ не тянет — ёмкость), нужна история/перечитывание задач (аудит — event sourcing); когда RabbitMQ лучше: умеренный throughput со сложной логикой ретраев/DLQ/маршрутизации (задачи с ретраями — RabbitMQ декларативнее — Celery); «Kafka вместо RabbitMQ для задач» — работает, но руками больше — выбор — по модели, не по «один брокер на всё» — техдолг.

Что с гарантиями доставки — у кого надёжнее? Оба дают at-least-once при правильной настройке (повторы — идемпотентность обязательна — в обоих); RabbitMQ: publisher confirms (продюсер знает, что broker принял — очереди), consumer ack (обработано → ack → удаление — unacked при падении → redelivery), quorum queues (Raft-репликация — консенсус — переживает узел), transient→persistent (сообщения на диске — не теряются при рестарте — надёжность); Kafka: producer acks=all (репликация на все ISR — consumer), offset-коммит после обработки (at-least-once — consumer), репликация партиций (leader-follower — failover), exactly-once (транзакции + read_committed — но граница с внешней БД — outbox — saga); «надёжнее» — не про брокер, а про настройку + идемпотентность потребителя (оба теряют при auto-commit/без confirms — consumer — очереди — надёжность проектируют, не выбирают брокером — надёжность-дизайн); критерий: оба надёжны при правильной конфигурации + идемпотентность — идемпотентность — обязательна в обоих.

Kafka без ZooKeeper (KRaft) — что изменилось? KRaft (Kafka 3.3+ production-ready) — замена ZooKeeper встроенным Raft-консенсусом (консенсус — metadata в самой Kafka — controller-ноды); выигрыш: проще деплой (нет отдельного ZooKeeper-ансамбля — меньше компонентов — docker-compose), быстрее масштабирование (metadata-операции — партиции создаются быстрее — тысячи партиций — KRaft справляется лучше), меньше операционных сущностей (один кластер вместо двух — Kafka + ZooKeeper — эксплуатация); миграция: ZooKeeper → KRaft (поэтапная — dual-mode переход — документация — миграция — новые кластеры сразу KRaft, старые — мигрируют при апгрейде — зависимости); «ZooKeeper ещё нужен?» — для legacy-кластеров до миграции, новые — KRaft (дефолт 3.7+ — Kafka); RabbitMQ-аналог: quorum queues (Raft — консенсус — «встроенный консенсус» — оба брокера идут к Raft — тренд — надёжность); вывод: KRaft упростил эксплуатацию Kafka (минус ZooKeeper), но Kafka всё равно тяжелее RabbitMQ на старте (партиции/топики/мониторинг — ёмкость — «Kafka стал проще» — да, но не «как RabbitMQ» — выбор).

Как мигрировать с RabbitMQ на Kafka (или обратно)? Полная миграция — редко оправдана (разные модели — дизайн — обычно гибрид — сценарий выше); если нужна: параллельный dual-publish (продюсер пишет в оба брокера — потребители мигрируют постепенно — миграция — сверка — тесты); мост-коннектор (RabbitMQ → Kafka через consumer-bridge (читает RabbitMQ, публикует Kafka) или Kafka Connect (RabbitMQ-source-коннектор — интеграция); семантические различия учтены: RabbitMQ-обработанное-удалено vs Kafka-хранится (очереди — «перечитывание» — новое поведение — потребители адаптируются — consumer), маршрутизация (RabbitMQ exchanges → Kafka-топики + ключ-партиционирование — event-driven), DLQ (RabbitMQ DLX → Kafka DLQ-топик — consumer); обратная миграция (Kafka → RabbitMQ) — реже (если «Kafka оказался избыточен» — выбор — но «перечитывание» теряется — event sourcing); практика: мигрировать по доменам (один поток за раз — техдолг-волны), не big-bang — миграция-дисциплина — гибрид часто конечная точка, не переходный этап — микросервисы.

Источники: документация Apache Kafka, RabbitMQ (quorum queues) — ссылки в шапке.