Архитектура Kafka
Apache Kafka — это распределённая платформа для потоковой передачи данных, построенная как неизменяемый упорядоченный журнал (log), а не классическая очередь. Ключевые компоненты: топик (категория сообщений), партиции (единицы параллелизма и порядка — порядок гарантирован только внутри партиции), offset (позиция сообщения в партиции), продюсер (публикует сообщения с выбором партиции по ключу или round-robin), консьюмер (читает сообщения, объединяясь в группы — каждая партиция читается только одним консьюмером из группы), брокеры (серверы, образующие кластер с репликацией), ISR (реплики, успевающие за лидером) и ZooKeeper/KRaft (координация кластера). Kafka обеспечивает высокую пропускную способность, хранение истории (retention по времени или объёму) и replay, но не гарантирует глобальный порядок (требует одной партиции) и не удаляет сообщения после прочтения. Используется для high-load сценариев, потоковой обработки (Kafka Streams) и событийной архитектуры, но не подходит для простых очередей или низких задержек.
Введение: Журнал, а не почтовый ящик
Представьте банковскую выписку по счёту. В ней записаны все операции в порядке их совершения. Вы не можете изменить прошлые записи — только добавить новые. Любой может прочитать выписку с любого момента. Выписка хранится годами.
Apache Kafka устроена как такая выписка. Это не почтовый ящик (где сообщение исчезает после прочтения). Это журнал (log) — упорядоченная, неизменяемая последовательность сообщений, которая хранится определённое время.
Apache Kafka — это распределённая платформа для потоковой передачи данных. Она сочетает в себе возможности брокера сообщений, хранилища данных и движка потоковой обработки.
Для системного аналитика Kafka — это инструмент для сценариев с высокими нагрузками, где важны порядок сообщений, хранение истории и возможность повторного чтения. Kafka не заменяет очереди (RabbitMQ) — они решают разные задачи.
Ключевая идея: Журнал (Log)
Тема "user_events" (журнал):
+---------+---------+---------+---------+
| Сообщение 0 | Сообщение 1 | Сообщение 2 | Сообщение 3 | ...
+---------+---------+---------+---------+
Offset: 0 1 2 3Свойства журнала:
| Свойство | Значение |
|---|---|
| Упорядоченность | Сообщения имеют порядок (offset) |
| Неизменяемость | Нельзя изменить или удалить сообщение |
| Хранение | Сообщения хранятся определённое время |
| Replay | Можно перечитать сообщения с любого места |
В отличие от очередей (RabbitMQ), где сообщение удаляется после прочтения, в Kafka сообщение остаётся в журнале. Несколько потребителей могут читать одно и то же сообщение независимо.
Основные компоненты
graph TD
P[Продюсер] --> T[Топик]
T --> C[Партиция 0]
T --> D[Партиция 1]
T --> E[Партиция 2]
C --> CG[Consumer Group A]
D --> CG
E --> CG
Топик (Topic)
Категория или канал, куда публикуются сообщения. Аналог таблицы в базе данных.
Партиция (Partition)
Топик разбивается на партиции. Каждая партиция — это упорядоченный журнал сообщений.
| Характеристика | Значение |
|---|---|
| Порядок | Гарантирован внутри партиции |
| Параллелизм | Разные партиции могут читаться параллельно |
| Количество | Определяет максимальную степень параллелизма |
Offset (Смещение)
Уникальный идентификатор сообщения внутри партиции. Последовательное целое число.
Партиция 0:
offset 0: {user_id: 123, action: "login"}
offset 1: {user_id: 123, action: "search"}
offset 2: {user_id: 456, action: "login"}Продюсер (Producer)
Отправляет сообщения в топик.
Выбор партиции:
| Стратегия | Как работает |
|---|---|
| Round-robin | По очереди во все партиции |
| По ключу | hash(key) % partitions — все сообщения с одним ключом попадают в одну партицию |
| Указана явно | Продюсер сам решает |
Пример ключа: user_id — все события одного пользователя в одной партиции → порядок гарантирован.
Консьюмер (Consumer)
Читает сообщения из топика.
Consumer Group (Группа консьюмеров)
Несколько консьюмеров объединяются в группу. Каждая партиция читается одним консьюмером из группы.
graph LR
P[Партиция 0] --> C1[Консьюмер 1]
P2[Партиция 1] --> C2[Консьюмер 2]
P3[Партиция 2] --> C2
Правила:
| Ситуация | Результат |
|---|---|
| Партиций больше, чем консьюмеров | Некоторые консьюмеры читают несколько партиций |
| Консьюмеров больше, чем партиций | Лишние консьюмеры простаивают |
Брокер (Broker)
Сервер Kafka, который хранит партиции и обслуживает запросы.
Кластер
Несколько брокеров образуют кластер. Один брокер — лидер (leader) партиции, другие — реплики (followers).
graph TD
subgraph "Кластер Kafka"
B1[Брокер 1<br>Лидер партиции 0]
B2[Брокер 2<br>Лидер партиции 1<br>Реплика партиции 0]
B3[Брокер 3<br>Лидер партиции 2<br>Реплика партиции 1]
end
Controller
Один из брокеров выполняет роль контроллера: управляет лидерами партиций, обрабатывает отказы.
Порядок сообщений
| Уровень | Гарантия |
|---|---|
| Внутри партиции | Строгий порядок (offset) |
| Между партициями | Порядок не гарантирован |
| Глобальный порядок | Только если партиция одна (не масштабируется) |
Как гарантировать порядок для одного пользователя: использовать user_id как ключ → все события пользователя в одной партиции.
Хранение данных
Retention (Срок хранения)
| Параметр | Значение по умолчанию |
|---|---|
| По времени | 7 дней |
| По объёму | 1 ГБ на партицию |
После истечения срока или превышения объёма старые сообщения удаляются.
Сегменты
Лог разбивается на сегменты (обычно 1 ГБ). Активный сегмент — тот, куда пишутся новые сообщения. Запечатанные сегменты доступны только для чтения и удаляются при устаревании.
Репликация
graph LR
L[Лидер] --> F1[Реплика 1]
L --> F2[Реплика 2]
Параметры репликации:
| Параметр | Значение |
|---|---|
replication.factor | Количество копий (обычно 3) |
min.insync.replicas | Минимум реплик, которые должны подтвердить запись |
ACKS (подтверждения):
| acks | Гарантия |
|---|---|
| 0 | Сообщение может потеряться |
| 1 | Лидер подтвердил (может потеряться, если лидер упал до репликации) |
| all | Все реплики в ISR подтвердили |
ISR (In-Sync Replicas)
Реплики, которые успевают за лидером.
Реплика в ISR:
- replication lag < параметры
- zookeeper connection aliveЕсли реплика отстала, она исключается из ISR. Запись считается успешной, если подтвердили все реплики из ISR.
ZooKeeper / KRaft
ZooKeeper (классическая)
Координирует кластер: хранит метаданные, выбирает контроллера, отслеживает состояние брокеров.
Недостатки: ZooKeeper — отдельная система, требует администрирования, не очень быстрая.
KRaft (Kafka Raft)
Начиная с версии 2.8, Kafka может работать без ZooKeeper. Контроллеры управляют метаданными через Raft-консенсус.
Преимущества: Проще администрирование, быстрее, масштабируемость до миллионов партиций.
Producer и Consumer в деталях
Продюсер (Producer)
Компоненты:
- Serializer: объект → байты
- Partitioner: определяет партицию
- Compressor: сжатие (gzip, snappy, lz4, zstd)
- Buffer: накопление сообщений перед отправкойКонсьюмер (Consumer)
Компоненты:
- Deserializer: байты → объект
- Commit offset: сохранение позиции
- Rebalance listener: реакция на перераспределение партицийConsumer Group Rebalance
При добавлении/удалении консьюмера партиции перераспределяются. Во время ребаланса консьюмеры не читают.
Потоковая обработка (Kafka Streams)
Kafka Streams — библиотека для обработки потоков данных внутри Kafka.
graph LR
A[Входной топик] --> B[Kafka Streams]
B --> C[Выходной топик]
Возможности:
- Фильтрация, маппинг
- Агрегации по окнам
- Join потоков
- Stateful обработка (хранит состояние в RocksDB)
Когда Kafka — хороший выбор
| Сценарий | Почему |
|---|---|
| Высокая нагрузка | Миллионы сообщений в секунду |
| Важен порядок | Гарантия внутри партиции |
| Хранение истории | Retention, replay |
| Много подписчиков | Каждый читает независимо |
| Потоковая обработка | Kafka Streams, ksqlDB |
Когда Kafka — не лучший выбор
| Сценарий | Почему |
|---|---|
| Нужна очередь с гарантией однократной доставки | Kafka не удаляет сообщения |
| Мало сообщений (<1000/сек) | Избыточно, RabbitMQ проще |
| Сложная маршрутизация | RabbitMQ гибче |
| Задержка важнее пропускной способности | Kafka оптимизирована на throughput, не latency |
Резюме
Apache Kafka — распределённый журнал (log), а не очередь. Сообщения не удаляются после прочтения.
Топик разбивается на партиции. Порядок гарантирован внутри партиции.
Продюсер пишет в партиции (round-robin или по ключу).
Консьюмеры объединяются в группы. Одна партиция — одному консьюмеру в группе.
Брокеры образуют кластер. Репликация обеспечивает надёжность.
ISR (In-Sync Replicas) — реплики, которые успевают за лидером.
ZooKeeper / KRaft — координация кластера.