Apache Kafka
Apache Kafka — распределённая платформа потоковой передачи событий: продюсеры пишут сообщения в топики, а консьюмеры читают их из лога на диске в своём темпе.
Что такое Apache Kafka
Apache Kafka (в разговоре — «кафка») — распределённая платформа потоковой передачи событий. Продюсеры пишут сообщения в топики, Kafka складывает их на диск в виде упорядоченного лога, а консьюмеры читают этот лог сами и в своём темпе. Проект вырос из внутренней разработки LinkedIn, с 2011 года развивается в Apache Software Foundation; сервер написан на Scala и Java, работает на JVM, слушает порт 9092.
Простыми словами: Kafka — не почтовый ящик, а журнал. Обычный брокер сообщений удаляет сообщение, как только его забрали. Kafka дописывает события в конец файла и хранит их заданный срок независимо от того, кто и сколько раз их прочитал. Отсюда и все её свойства: можно перечитать историю, можно подключить нового читателя задним числом, можно читать один поток десятью сервисами сразу.
Топики, партиции и offset
Топик — именованный поток событий (orders, clicks). Физически он нарезан на партиции, и каждая партиция — независимый append-only лог. У сообщения внутри партиции есть offset: порядковый номер, который не меняется никогда.
Топик "orders", 3 партиции:
P0: [0][1][2][3][4] ← продюсер всегда дописывает в конец
P1: [0][1][2]
P2: [0][1][2][3][4][5]
↑
консьюмер читает с offset=2 и сам двигает курсор
Партицию выбирает ключ сообщения: hash(key) % число_партиций. Отсюда главное практическое правило — порядок гарантирован только внутри партиции, а не внутри топика. Нужен строгий порядок событий по клиенту — ставьте key = client_id: все его события лягут в одну партицию и будут прочитаны последовательно. Глобального порядка по всему топику Kafka не даёт и не обещает.
Consumer group: как масштабируется чтение
Консьюмеры объединяются в группу (group.id), и Kafka распределяет партиции между её участниками так, что одну партицию в каждый момент читает ровно один консьюмер группы. Следствие: число партиций — это потолок параллелизма. Шесть партиций — максимум шесть работающих консьюмеров, седьмой будет простаивать.
Разные группы читают тот же топик независимо и не мешают друг другу: один поток событий одновременно уходит и в биллинг, и в аналитику, и в поиск.
Прогресс группы — это закоммиченный offset. Разрыв между последним записанным и закоммиченным offset называется consumer lag и служит главной метрикой здоровья: растёт lag — консьюмеры не успевают за продюсерами. Следить за ним стоит с самого начала, наравне с обычным health check.
Надёжность: репликация и acks
Каждая партиция реплицируется на несколько брокеров: один лидер, остальные — follower'ы. Реплики, догнавшие лидера, образуют ISR (in-sync replicas).
acks |
Когда запись считается успешной | Риск |
|---|---|---|
0 |
Сразу после отправки | Потеря при любом сбое |
1 |
Лидер записал к себе | Потеря, если лидер упал до репликации |
all |
Записали все реплики из ISR | Минимальный, ценой задержки |
Рабочий продакшн-набор: acks=all, replication.factor=3, min.insync.replicas=2 — кластер переживает потерю одного брокера без потери данных. Плюс enable.idempotence=true, чтобы повторы продюсера при таймаутах не порождали дубли. Координацию кластера в актуальных версиях обеспечивает встроенный KRaft, отдельный ZooKeeper больше не нужен.
Хранение: сообщения живут по таймеру
retention.ms=604800000 # 7 дней — значение по умолчанию
retention.bytes=-1 # без лимита на размер партиции
cleanup.policy=delete # delete — удалять старое по сроку
# compact — хранить последнее значение по каждому ключу
Compaction превращает топик в снимок состояния: для каждого ключа остаётся только самое свежее сообщение — так хранят, например, актуальный профиль пользователя. Возможность перечитать историю обычно и есть причина выбрать Kafka: новый сервис поднимается, проигрывает поток с offset=0 и строит своё состояние, никому не мешая.
Kafka vs RabbitMQ
| Apache Kafka | RabbitMQ | |
|---|---|---|
| Модель | Лог: сообщение остаётся после чтения | Очередь: сообщение исчезает после ack |
| Кто маршрутизирует | Консьюмер сам выбирает топик и offset | Брокер — через exchange и routing key |
| Перечитать историю | Да, сдвигом offset | Нет |
| Порядок | Внутри партиции | Внутри очереди |
| Сильная сторона | Поток событий, высокая пропускная способность | Гибкая раздача задач воркерам, приоритеты, retry |
Когда Kafka уместна, а когда нет
- Да: событийная шина между микросервисами, сбор кликов, логов и метрик, поставка данных в ClickHouse или DWH, CDC-поток изменений из PostgreSQL, пересчёт истории на новой логике.
- Нет: десяток задач в сутки, приоритеты сообщений, отложенная доставка «через 30 минут», индивидуальный retry каждого сообщения. Здесь Kafka — лишняя сложность, а RabbitMQ или NATS решают задачу проще.
По ресурсам Kafka упирается в диск и сеть, а не в CPU: она пишет последовательно и отдаёт данные из page cache. Значит — NVMe под логи, запас по пропускной способности сети и минимум три брокера, иначе репликация теряет смысл.
Связанные термины
- Брокеры сообщений — общий класс систем, к которому относится Kafka
- RabbitMQ — брокер с противоположной моделью: очередь вместо лога
- NATS — лёгкая альтернатива, когда не нужна экосистема Kafka
- Микросервисы и монолит — архитектура, ради которой обычно ставят Kafka
- ClickHouse — типичный приёмник событий из Kafka
- Кластер — Kafka разворачивается только кластером
Готовы запустить GPU-задачу?
Запустить GPU-сервер