Kafka vs RabbitMQ¶
Конспект видео «Kafka vs RabbitMQ на примерах | Распределенные системы и system design»
1. Зачем они нужны¶
И Kafka, и RabbitMQ работают как буфер сообщений между системами. Они дают слабую связанность: система A не обращается к системе B напрямую, а кладёт сообщение в буфер. Система B забирает его оттуда и обрабатывает в своём темпе.
2. Ключевые различия¶
2.1. Порядок обработки¶
| Kafka | RabbitMQ | |
|---|---|---|
| Структура | Лог, в который можно только дописывать (append-only) | Очередь FIFO |
| Чтение | Каждую партицию читает ровно один консьюмер из группы | Несколько консьюмеров конкурируют за сообщения одной очереди |
| Порядок | Гарантирован внутри партиции (не глобально) | Не гарантирован: консьюмеры работают с разной скоростью |
Масштабирование в Kafka: лог делится на партиции на разных машинах кластера. Все консьюмеры одной consumer group выполняют один и тот же код над сообщениями.
2.2. Хранение (персистентность)¶
- Kafka всегда пишет сообщения на диск.
- RabbitMQ по умолчанию хранит их в памяти, это быстро. Можно включить запись ещё и на диск, чтобы сообщения переживали рестарт или падение сервера.
2.3. Модель доставки¶
- RabbitMQ использует push: брокер сам отправляет сообщение консьюмеру, как только оно появилось. Так получается низкая задержка (latency).
- Kafka использует pull: консьюмер сам периодически забирает сообщения пачками (batch). Так получается высокая пропускная способность (throughput), потому что нет накладных расходов на каждое отдельное сообщение.
2.4. Скорость записи на диск¶
- В Kafka запись на диск означает простое добавление в конец файла. Это дёшево.
- В RabbitMQ запись на диск идёт в более сложную структуру данных (очередь). При большом потоке событий он может не справиться.
2.5. Масштабирование консьюмеров¶
- RabbitMQ: достаточно добавить воркеров, и задачи будут разбираться быстрее.
- Kafka: параллелизм ограничен числом партиций. Увеличение их числа требует миграции и даётся сложно.
3. Где что применять¶
3.1. Kafka: перенос состояния (state) из одной системы в другую¶
Задача: отразить состояние одной системы в другой. Требования:
- Надёжность (durability). Нельзя терять обновления. Они логически зависят друг от друга, и потеря одного делает бессмысленными все последующие.
- Порядок. Обновления нужно применять в той же последовательности, в какой они произошли.
Durability дают обе системы, а порядок только Kafka. Kafka сама не даёт подключить больше одного консьюмера на партицию. В RabbitMQ такую защиту пришлось бы писать самим.
Примеры:
- БД → поисковый индекс и аналитическое хранилище (data warehouse), то есть репликация обновлений.
- Instagram (типичная задача на system design): сервис постов → сервис ленты (feed), который обновляет ленты подписчиков.
3.2. RabbitMQ: коммуникация между сервисами (раздача задач)¶
Задача: один сервис раздаёт работу другому.
Примеры:
- YouTube: видеосервис раздаёт воркерам чанки загруженного видео на обработку.
- В Kafka один медленный чанк заблокирует все чанки за ним в той же партиции (head-of-line blocking).
- В RabbitMQ медленный чанк касается только одного консьюмера, остальные продолжают работать.
- Обработку легко ускорить, просто добавив воркеров.
- Такси: сервис матчинга передаёт сервису водителей новые предложения поездок.
- Плохое соединение у одного водителя не должно тормозить остальных.
- Нужна низкая задержка, и хранение в памяти у RabbitMQ даёт её лучше, чем запись на диск у Kafka.
3.3. Серая зона: подходят обе системы¶
Ситуация: события из системы A просто копируются в систему B (например, сохраняются на диск). Порядок не важен, то есть это не перенос состояния. Полезной работы на стороне B нет, то есть это и не раздача задач.
| Требование | Выбор |
|---|---|
| Событий много, нужна высокая пропускная способность | Kafka (дешёвая запись в конец файла, pull пачками) |
| Событий мало, нужна низкая задержка | RabbitMQ (push-модель) |
| Часть событий можно терять (durability не нужна) | RabbitMQ (хранение только в памяти) |
4. Итог¶
- Kafka нужна, когда надо перенести состояние из одной системы в другую. Важны надёжность и порядок.
- RabbitMQ нужен для раздачи задач между сервисами. Важны независимость консьюмеров, простое масштабирование и низкая задержка.
- Пограничный случай решается вопросом «что важнее?»: пропускная способность, тогда Kafka, или задержка, тогда RabbitMQ.