Когда использовать Kafka
Kafka — правильный выбор для сценариев с высокой нагрузкой (миллионы сообщений/сек), когда важен порядок сообщений (гарантируется внутри партиции через ключ), нужно хранить историю и перечитывать её (retention, replay), а также когда одно сообщение должны получать несколько независимых потребителей или требуется потоковая обработка (Kafka Streams, ksqlDB). Kafka не подходит для классических очередей задач (сообщение должно удаляться после обработки), для сложной маршрутизации, для низкой задержки (оптимизирована на throughput, а не latency), для малых объёмов (избыточна) и для команд без опыта (сложна в эксплуатации). Основной выбор: Kafka для событийных потоков, истории и аналитики; RabbitMQ для очередей задач, RPC и сложной маршрутизации.
Введение: Не молоток для всех гвоздей
Представьте, что вам нужно забить гвоздь. Можно использовать молоток — быстро и эффективно. Можно использовать микроскоп — он тоже ударит, но это странно и неудобно. А можно использовать экскаватор — он справится, но это безумно дорого и сложно.
Apache Kafka — это экскаватор. Очень мощный, очень масштабируемый, очень надёжный. Но он сложен и требует ресурсов. Использовать Kafka для отправки нескольких сообщений в день — как вызывать экскаватор, чтобы забить один маленький гвоздь.
Выбор между Kafka и другими инструментами — это не вопрос “что лучше”. Это вопрос “что подходит для вашей задачи”. Kafka решает одни проблемы блестяще, для других — совершенно не подходит.
Для системного аналитика понимание, когда использовать Kafka, — это умение соотносить требования проекта с сильными и слабыми сторонами инструмента. Это позволяет избежать как недоинжиниринга (когда простой брокер не справляется), так и переинжиниринга (когда Kafka добавляет сложность без необходимости).
Признаки того, что Kafka — хороший выбор
1. Высокая нагрузка на запись (High Throughput)
Вам нужно обрабатывать миллионы сообщений в секунду. Kafka спроектирована для этого.
| Показатель | Kafka | Типичный брокер (RabbitMQ) |
|---|---|---|
| Сообщений в секунду | Миллионы | Тысячи — десятки тысяч |
| Размер сообщения | До 1 МБ (по умолчанию), можно больше | Ограничен |
Почему Kafka справляется: Оптимизация на уровне операционной системы (page cache, нулевое копирование), пакетная обработка, последовательная запись на диск.
Когда это важно: Телеметрия, логгирование, метрики, IoT, финансовые транзакции (биржи).
2. Важен порядок сообщений (Ordering)
Вам нужно, чтобы сообщения обрабатывались в том же порядке, в котором были отправлены. Kafka гарантирует порядок внутри партиции.
Пример: Все события одного банковского счёта должны обрабатываться строго по порядку. Нельзя списать деньги до того, как они поступили.
Как Kafka решает: Используется ключ (например, ID счёта). Все сообщения с одним ключом попадают в одну партицию. Порядок гарантирован.
Почему это сложно в других брокерах: В классических очередях порядок не гарантирован (если несколько потребителей). В RabbitMQ можно сделать один потребитель на очередь, но это убивает масштабирование.
3. Нужно хранить историю и перечитывать (Replay)
Вам нужно не только обрабатывать сообщения в реальном времени, но и иметь возможность перечитать историю.
Пример: Новый сервис аналитики должен обработать все события за последнюю неделю, чтобы построить модели.
Как Kafka решает: Сообщения не удаляются после прочтения. Хранятся дни, недели, месяцы (retention). Можно начать чтение с любого offset.
Почему это невозможно в других брокерах: В RabbitMQ сообщение удаляется, как только подтверждено потребителем. Нет истории.
4. Много независимых потребителей (Multiple Subscribers)
Одно сообщение должны получить несколько независимых систем.
Пример: Событие “пользователь создан” нужно отправить в CRM, биллинг, маркетинг, службу безопасности.
Как Kafka решает: Топик. Каждый потребитель читает независимо со своим offset. Если новый потребитель добавился, он может прочитать историю с начала.
Почему это возможно в Kafka, но сложно в других брокерах: В RabbitMQ нужно создавать отдельную очередь для каждого потребителя и копировать сообщения. Это возможно, но менее эффективно.
5. Потоковая обработка (Stream Processing)
Вам нужно обрабатывать данные в реальном времени: агрегировать, фильтровать, обогащать, соединять потоки.
Пример: Подсчёт количества кликов по окнам в 5 минут. Обнаружение аномалий в потоке данных.
Как Kafka решает: Kafka Streams (библиотека) и ksqlDB (SQL для потоков) позволяют делать это внутри экосистемы Kafka.
Почему это сложно в других брокерах: Нет встроенных инструментов для потоковой обработки. Пришлось бы выгружать данные в отдельную систему (Spark, Flink).
Признаки того, что Kafka — плохой выбор
1. Мало сообщений (Low Throughput)
У вас несколько сообщений в секунду или в минуту. Kafka справится, но это как стрелять из пушки по воробьям.
Почему плохо: Kafka имеет накладные расходы. Ей нужно несколько брокеров, ZooKeeper (или KRaft), настройка. Для малых объёмов RabbitMQ или даже простая база данных будут проще и дешевле.
Пример: Внутренняя система учёта с десятком операций в день.
2. Нужна сложная маршрутизация (Complex Routing)
Сообщения должны направляться по разным очередям в зависимости от содержимого, с разными правилами.
Пример: Заказы из Москвы — в одну очередь, из СПб — в другую, срочные заказы — в приоритетную.
Как Kafka справляется: Kafka не имеет встроенной гибкой маршрутизации. Это можно сделать через отдельный потоковый процесс (Kafka Streams), но это дополнительный код и сложность.
Почему RabbitMQ лучше: RabbitMQ изначально спроектирован для сложной маршрутизации (exchanges, bindings, routing keys). Это его родная стихия.
3. Нужна гарантия “ровно один раз” для каждого сообщения (Exactly-Once per message)
Вам нужно, чтобы каждое сообщение было обработано ровно один раз, без дубликатов и без потерь.
Как Kafka решает: Kafka может обеспечить exactly-once для потока (stream processing), но не для индивидуального сообщения в очереди. Для сценария “отправил — один потребитель получил один раз” Kafka не подходит, потому что сообщение могут прочитать несколько потребителей из разных групп.
Почему RabbitMQ может быть лучше: RabbitMQ с подтверждениями и ручным ack может гарантировать, что сообщение будет обработано один раз (at-least-once + идемпотентность на стороне потребителя). Но именно exactly-once в классическом смысле сложен везде.
4. Нужна низкая задержка (Low Latency)
Сообщение должно быть доставлено за миллисекунды.
Как Kafka работает: Kafka оптимизирована на пропускную способность, а не на задержку. Сообщения могут накапливаться в буфере (batch). Задержка может составлять десятки миллисекунд.
Почему RabbitMQ лучше: RabbitMQ может отправлять сообщения по одному, задержка меньше.
Пример: Система управления роботом, где команда должна исполниться мгновенно. Kafka не подойдёт.
5. Нужно удалять сообщения после обработки (Queue semantics)
Вам нужно, чтобы сообщение исчезло после того, как его обработал один потребитель. Это классическая очередь.
Как Kafka работает: Kafka не удаляет сообщения. Они остаются в журнале. Это не очередь, а журнал.
Почему RabbitMQ лучше: RabbitMQ — классическая очередь. Сообщение удаляется после подтверждения. Это именно то, что нужно для сценариев “задача должна быть выполнена один раз”.
Пример: Очередь задач для воркеров. Каждую задачу должен взять и выполнить один воркер. Здесь RabbitMQ подходит лучше.
6. Маленькая команда, нет опыта
У вас небольшая команда, никто не знает Kafka. Настройка и поддержка Kafka требуют квалификации.
Почему плохо: Kafka — сложная система. Неправильная настройка приводит к потере данных, падению кластера, проблемам с производительностью.
Что выбрать: Управляемый брокер (AWS SQS, Google Pub/Sub) или RabbitMQ.
Kafka vs RabbitMQ: Ключевые различия
| Характеристика | Kafka | RabbitMQ |
|---|---|---|
| Модель | Журнал (log) | Очередь (queue) |
| После прочтения | Сообщение остаётся | Сообщение удаляется |
| Повторное чтение | Да (replay) | Нет |
| Порядок | Внутри партиции | Не гарантирован (если не один потребитель) |
| Маршрутизация | Простая (топики) | Сложная (exchanges, bindings) |
| Задержка | Миллисекунды (может быть выше) | Миллисекунды (ниже) |
| Пропускная способность | Миллионы сообщений/сек | Тысячи — десятки тысяч |
| Хранение истории | Да (retention) | Нет (только пока не доставлено) |
| Сложность | Высокая | Средняя |
| Типичное применение | Потоки событий, аналитика | Очереди задач, RPC |
Сравнение с другими брокерами
| Брокер | Сильные стороны | Слабые стороны |
|---|---|---|
| Apache Kafka | Потоки, история, высокая нагрузка | Сложность, не для очередей |
| RabbitMQ | Очереди, маршрутизация, простота | Нет истории, меньшая нагрузка |
| AWS SQS | Простота, управляемый | Ограниченная функциональность, привязка к AWS |
| Redis Pub/Sub | Простота, скорость | Нет персистентности, нет истории |
| NATS | Скорость, простота | Нет истории, меньше функций |
Практические сценарии
Сценарий 1: Система логирования и метрик
Требования:
- 1 миллион сообщений в секунду
- Нужно хранить логи 7 дней
- Несколько систем читают логи (ELK, аналитика, мониторинг)
Выбор: Kafka
Почему: Высокая нагрузка, хранение истории, много потребителей.
Сценарий 2: Очередь задач для воркеров
Требования:
- Задачи создаются пользователями
- Воркеры берут задачи и выполняют
- Задача должна быть выполнена ровно один раз
Выбор: RabbitMQ (или SQS)
Почему: Классическая очередь. Сообщение должно исчезнуть после обработки. Kafka не подходит.
Сценарий 3: Событийная архитектура микросервисов
Требования:
- Сервисы общаются через события
- Нужна возможность перечитать историю (новый сервис)
- Важен порядок событий
Выбор: Kafka
Почему: Хранение истории, replay, порядок.
Сценарий 4: Команды управления роботом
Требования:
- Сообщения должны доставляться с задержкой < 5 мс
- Каждое сообщение критично
Выбор: RabbitMQ (или NATS)
Почему: Kafka не даёт такой низкой задержки.
Сценарий 5: Аналитика на потоковых данных
Требования:
- Агрегации по окнам
- Обнаружение аномалий в реальном времени
Выбор: Kafka + Kafka Streams
Почему: Встроенные инструменты для потоковой обработки.
Рекомендации по выбору
| Если вам нужно… | Выбирайте |
|---|---|
| Хранить историю событий | Kafka |
| Перечитывать сообщения | Kafka |
| Высокую нагрузку (миллионы/сек) | Kafka |
| Порядок сообщений | Kafka |
| Потоковую обработку | Kafka + Kafka Streams |
| Обычную очередь задач | RabbitMQ или SQS |
| Сложную маршрутизацию | RabbitMQ |
| Низкую задержку | RabbitMQ или NATS |
| Простоту и управляемость (в облаке) | SQS, Google Pub/Sub |
| Маленький проект, мало сообщений | PostgreSQL (таблица очереди) |
Распространённые ошибки
Ошибка 1: Kafka для очереди задач
Используют Kafka как очередь. Сообщения не удаляются, накапливаются. Потребители могут прочитать одно сообщение несколько раз (разные группы).
Решение: Для очереди задач используйте RabbitMQ.
Ошибка 2: Kafka без истории
Устанавливают retention = 1 час. Потеряли возможность replay.
Решение: Если не нужна история, зачем Kafka?
Ошибка 3: Kafka для малых объёмов
Десяток сообщений в день, но “Kafka же круто”.
Решение: PostgreSQL или простой брокер будет проще и дешевле.
Ошибка 4: Игнорирование сложности
Команда не знает Kafka, но решили использовать “потому что это стандарт”. Кластер падает, данные теряются.
Решение: Оценить компетенции команды. Использовать управляемый сервис (Confluent Cloud, AWS MSK) или выбрать более простой инструмент.
Ошибка 5: Смешение концепций
Пытаются реализовать request-response через Kafka (синхронный вызов). Kafka не для этого.
Решение: Для синхронных вызовов используйте HTTP/gRPC.
Резюме
Kafka — для потоков событий, истории, высокой нагрузки. Не для очередей задач, не для низкой задержки, не для маленьких проектов.
Kafka хороша, когда: нужно хранить историю, перечитывать сообщения, высокая нагрузка, важен порядок, много независимых потребителей, потоковая обработка.
Kafka плоха, когда: мало сообщений, нужна сложная маршрутизация, нужна низкая задержка, нужно удалять сообщения после обработки, маленькая команда.
RabbitMQ — для очередей задач, сложной маршрутизации, низкой задержки.
Выбор инструмента — это компромисс между функциональностью, сложностью и стоимостью. Kafka решает одни проблемы блестяще, для других не подходит.