Главное различие — модель данных:
- AMQP/RabbitMQ: сообщение — это задача в очереди. Поступило, было обработано, удалилось.
- Kafka: сообщение — это запись в логе. Поступило, осталось на время retention, может быть прочитано множеством потребителей по offset.
Из этого вытекают все остальные различия. Эта статья — семь конкретных критериев выбора между ними.
Семь критериев
1. Что вы пересылаете — задачи или события?
Задача (command) — кому-то надо что-то сделать. «Отправить email», «обработать изображение», «выставить счёт».
Событие (event) — что-то уже произошло, надо это записать или отреагировать. «Заказ создан», «платёж проведён», «пользователь зарегистрировался».
| Природа | Лучше |
|---|---|
| Задача исполнителя из пула | AMQP — work queue естественен |
| Событие в иерархии (broadcast многим) | Возможно AMQP (fanout/topic), возможно Kafka |
| Event log с возможностью реплея | Kafka |
«Задачи» обычно — AMQP. «События в системе» — обе работают, но Kafka выигрывает на сценариях, где новый сервис должен подписаться на историю (поднялся новая аналитика — пробежался по событиям за месяц).
2. Ordering
| AMQP | Kafka | |
|---|---|---|
| Гарантия порядка | В пределах queue (но не при параллельных consumer'ах) | В пределах партиции |
| Параллелизм без потери порядка | Сложно: или один consumer, или дробить на queue | Естественно: ключ → партиция, в партиции порядок |
В Kafka «партиционирование по ключу» — типовой паттерн: события одного userId гарантированно идут в порядке, разные userId обрабатываются параллельно. В AMQP такой паттерн собирается руками — нужна consistent hash exchange plugin или sharding на стороне продьюсера.
Если нужны «события одного пользователя в строгом порядке» — Kafka даёт это бесплатно. В AMQP — оверхед или single-consumer (медленно).
3. Throughput
Грубые цифры на современном железе:
| Throughput | Размер сообщения | |
|---|---|---|
| RabbitMQ Classic non-persistent | 100K+ msg/sec на узел | оптимум 1–10 KB |
| RabbitMQ Quorum (durable) | 30–50K msg/sec на узел | оптимум 1–10 KB |
| Kafka (durable, w:all) | 500K–1M+ msg/sec на узел | хорошо переносит 1 KB – 1 MB |
Kafka строилась под высокий throughput, log-based архитектура с sequential I/O и batch processing для этого оптимальна. На сценариях с миллионами сообщений в секунду (IoT-телеметрия, click streams, logs) — Kafka единственный реалистичный выбор.
AMQP на тысячах сообщений в секунду чувствует себя комфортно, на десятках тысяч начинает потеть, на сотнях тысяч нужно несколько кластеров.
4. Retention и replay
AMQP: сообщение исчезает после ack. Если позже захотите его прочитать — поздно. RabbitMQ Streams (3.9+) добавляют log-сценарий, но это уже не классический AMQP.
Kafka: retention настраивается на уровне топика. По умолчанию — 7 дней; можно неделями, можно бесконечно (для compacted topics — только последняя версия по ключу). Новый сервис подписался — может пробежать всю историю и догнать.
| Нужно | Лучше |
|---|---|
| Reprocess: «новая логика, прогоним последнюю неделю заново» | Kafka |
| Late subscriber: «запустили analytics, хотим месяц истории» | Kafka |
| Audit trail событий | Kafka (или AMQP + дублирование в БД) |
| Просто доставить и забыть | AMQP |
5. Routing flexibility
AMQP: routing — на стороне брокера. Producer публикует в exchange, exchange по правилам binding раскладывает по queue. Producer не знает, кто consumer.
Kafka: routing — на стороне producer'а. Producer выбирает топик и ключ; кто читает топик — известно через consumer group. Изменение «кто читает что» — изменение конфигурации потребителей, не топологии брокера.
| Сценарий | Лучше |
|---|---|
| Динамически меняется кто слушает что | AMQP (изменение bindings без касания продьюсеров) |
| Hierarchical events с подпиской по паттерну | AMQP topic exchange |
| Стабильная топология «продьюсер пишет, N сервисов читают тот же лог» | Kafka |
| Pub/Sub без копирования данных | Kafka (просто новый consumer group) |
6. Push vs Pull
AMQP: брокер пушит сообщения консьюмеру. Управление потоком — через prefetch (сколько unacked держать в буфере). Если consumer медленнее producer — брокер сам тормозит publish через flow control.
Kafka: consumer пуллит сообщения по offset. Если consumer медленнее — он просто отстаёт (lag растёт), брокер от этого не страдает.
Практические следствия:
- Kafka проще выдерживает спайки нагрузки: продьюсер пишет в лог сколько угодно, consumer догоняет.
- AMQP в спайк включает backpressure до клиента — нужно явно обрабатывать.
- В AMQP
prefetch=1гарантирует «один обработчик не возьмёт второе сообщение до завершения первого». В Kafka такой контроль черезmax.poll.records=1, но семантика чуть другая.
7. Операционная сложность
| RabbitMQ | Kafka | |
|---|---|---|
| Минимальная prod-конфигурация | 3 узла | 3 broker + 3 controller (KRaft) |
| Базовое мониторирование | Management UI + Prometheus exporter | JMX + специализированные tools (Confluent Control Center, Burrow) |
| Стоимость операционной экспертизы | Средняя | Высокая |
| Cross-DC replication | Federation/Shovel — относительно просто | MirrorMaker 2 / Cluster Linking — требует понимания |
| Backup топологии | rabbitmqctl export_definitions | Tools специфичные, или kafka-acls/configs |
Kafka — серьёзная операционная инвестиция. Один раз сделать правильно — годы стабильности. Но «уволили DevOps, никто не знает как» — Kafka превращается в чёрный ящик быстрее, чем RabbitMQ.
Когда AMQP
- Worker queue на десятки тысяч сообщений в час, distribution из пула. Главный сценарий RabbitMQ.
- Cross-service RPC через брокер.
- Pub/Sub с broadcast'ом в десятки сервисов, где у каждого свой набор queue и они приходят/уходят (cache invalidation, config updates).
- Иерархическая routing через topic exchange — когда подписки гибко по паттерну.
- Команды с дедлайном: «обработать в течение 5 минут, после — не нужно» (TTL + DLX).
- Маленький-средний throughput с богатой маршрутизацией.
Когда Kafka
- Event log с retention: новые сервисы должны видеть историю.
- Высокий throughput (десятки тысяч+ сообщений в секунду).
- Партиционирование по ключу для горизонтального масштабирования с сохранением порядка per-key.
- Реплей и replay-debugging: «прогнать обработчик ещё раз на старых событиях».
- Streaming аналитика через Kafka Streams / Flink / Spark.
- Audit trail как первичный источник правды (event sourcing).
- CDC из БД (Debezium → Kafka).
Когда обе вместе
Не «возьмём обе на всякий случай», а конкретные сценарии:
AMQP для команд + Kafka для событий
Сервис принимает команды через AMQP (process-image, send-email — work queue от REST endpoint'а). Он же публикует факты случившегося в Kafka (image-processed, email-sent) — там их подбирают аналитика, мониторинг, ML-pipelines.
HTTP →─→ AMQP queue (command) →─→ Service →─→ Kafka topic (event)
↓
analytics, ML, audit
Команды атомарны, исчезают после обработки. События остаются для истории.
AMQP для tight coupling, Kafka для loose coupling
Когда два сервиса связаны контрактом и обработка должна произойти в realtime — AMQP. Когда событие может потребоваться кому угодно потом — Kafka.
Outbox: БД → AMQP, и Outbox → Kafka параллельно
Иногда нужно «обработать событие срочно одним сервисом и сохранить для всех остальных». БД-таблица outbox → один CDC-coupler пишет в AMQP (на конкретного исполнителя), второй в Kafka (для всех потребителей событий).
Сложно операционно — лучше иметь хорошее обоснование.
Антипаттерны
- «Возьмём RabbitMQ, потом перейдём на Kafka» — если данные нужны как event log, начинайте с Kafka. Миграция кода с queue-семантики на log-семантику — переписывание, не апгрейд.
- «Kafka, потому что Netflix её использует» — Netflix на десятках миллионов событий в секунду. У вас на нескольких тысячах — RabbitMQ проще и дешевле.
- «Сделаем queue в Kafka» — технически можно (один потребитель из одной партиции), но Kafka не оптимизирована под short-lived очереди. Worker queue на сотнях тысяч задач в день — лучше RabbitMQ.
- «Будем хранить запросы клиентов 30 дней в Kafka» — Kafka не БД. Если нужен ad-hoc query по содержимому — это event store + view БД (PostgreSQL/Mongo), не raw Kafka.
Шпаргалка
| Симптом | Брокер |
|---|---|
| «Распределить задачи между N workers» | RabbitMQ |
| «Каждый сервис должен узнать, что заказ создался» | Можно RabbitMQ (fanout) или Kafka — зависит от других пунктов |
| «Хочу прогнать процессор на событиях за неделю заново» | Kafka |
| «Нужно 1 000 000 событий в секунду» | Kafka |
| «RPC между сервисами без HTTP» | RabbitMQ |
«Иерархические события domain.entity.action» | RabbitMQ (topic) |
| «Event sourcing — события первичны» | Kafka |
| «CDC из БД» | Kafka |
| «Команды с дедлайном» | RabbitMQ (TTL) |
| «Streaming-аналитика» | Kafka |
Что почитать дальше
- Протокол AMQP — модель доставки RabbitMQ.
- Apache Kafka — основы — модель доставки Kafka.
- RabbitMQ в production и Kafka в production — операционные стороны обеих.
- Messaging-паттерны через AMQP — work queue, pub/sub, RPC, idempotency.
- Распределённые паттерны — Saga, Outbox, Idempotent Consumer (применимы к обеим).