Перейти к содержимому

Архитектура Kafka

Kafka как распределенный журнал событий: topic, partition, offset, producer, consumer group, broker, leader, replica, ISR.

Введение: Журнал, а не почтовый ящик

Представьте банковскую выписку по счёту. В ней записаны все операции в порядке их совершения. Вы не можете изменить прошлые записи — только добавить новые. Любой может прочитать выписку с любого момента. Выписка хранится годами.

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)

Topic — логический поток сообщений. Хорошее название topic должно отражать смысл потока, а не внутреннее имя сервиса. Категория или канал, куда публикуются сообщения. Аналог таблицы в базе данных.

Плохое наименование:

request-topic
service-a-events

Хорошее наименование:

termination-request-events
contract-status-events
payment-events

Партиция (Partition)

Topic физически разбивается на partitions. Partition — это упорядоченный журнал сообщений. Именно partition дает Kafka параллелизм и масштабирование.

ХарактеристикаЗначение
ПорядокГарантирован внутри партиции
ПараллелизмРазные партиции могут читаться параллельно
КоличествоОпределяет максимальную степень параллелизма
termination-request-events
  partition 0: offset 0, 1, 2...
  partition 1: offset 0, 1, 2...
  partition 2: offset 0, 1, 2...

Главное правило: порядок гарантируется только внутри одной partition. Между partitions глобального порядка нет.

Offset (Смещение)

Offset — позиция сообщения внутри partition. Он уникален только в рамках конкретной partition. Последовательное целое число.

Партиция 0:
  offset 0: {user_id: 123, action: "login"}
  offset 1: {user_id: 123, action: "search"}
  offset 2: {user_id: 456, action: "login"}

Продюсер (Producer)

Producer публикует сообщения. Он определяет topic, key, value, headers и уровень подтверждения записи. Producer не должен отправлять “просто JSON”. Он публикует событие с бизнес-смыслом.

Выбор партиции:

СтратегияКак работает
Round-robinПо очереди во все партиции
По ключуhash(key) % partitions — все сообщения с одним ключом попадают в одну партицию
Указана явноПродюсер сам решает

Пример события:

{
  "eventId": "8d1ad25d-23a1-4d99-a3e9-07d22e93a8e1",
  "eventType": "TerminationRequestCreated",
  "eventVersion": 1,
  "occurredAt": "2026-05-30T12:30:00Z",
  "requestId": "TR-100500",
  "contractId": "C-987654",
  "status": "CREATED"
}

Консьюмер (Consumer)

Читает сообщения из топика.

Consumer Group (Группа консьюмеров)

Consumer group — логический потребитель, который может состоять из нескольких экземпляров. Несколько консьюмеров объединяются в группу. Каждая партиция читается одним консьюмером из группы.

    graph LR
    P[Партиция 0] --> C1[Консьюмер 1]
    P2[Партиция 1] --> C2[Консьюмер 2]
    P3[Партиция 2] --> C2
  

Правила:

СитуацияРезультат
Партиций больше, чем консьюмеровНекоторые консьюмеры читают несколько партиций
Консьюмеров больше, чем партицийЛишние консьюмеры простаивают

Брокер (Broker), leader, replica

Broker — сервер Kafka, который хранит партиции и обслуживает запросы. Kafka cluster состоит из нескольких brokers. Для каждой partition один broker является leader, остальные — replicas/followers.

Producer пишет в leader. Followers копируют данные с leader. Если leader падает, Kafka выбирает нового leader из актуальных replicas.

Кластер

Несколько брокеров образуют кластер. Один брокер — лидер (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 — In-Sync Replicas, актуальные реплики, которые успевают за leader. Если replica отстает, она может быть исключена из ISR.

Реплика в 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

Резюме

  1. Apache Kafka — распределённый журнал (log), а не очередь. Сообщения не удаляются после прочтения.

  2. Топик разбивается на партиции. Порядок гарантирован внутри партиции.

  3. Продюсер пишет в партиции (round-robin или по ключу).

  4. Консьюмеры объединяются в группы. Одна партиция — одному консьюмеру в группе.

  5. Брокеры образуют кластер. Репликация обеспечивает надёжность.

  6. ISR (In-Sync Replicas) — реплики, которые успевают за лидером.

  7. ZooKeeper / KRaft — координация кластера.

Проверка знаний

Вопрос 1 из 4
Как лучше всего описать Kafka?
Что такое partition в Kafka?
Зачем consumer group в Kafka?
Что важно помнить о порядке в Kafka?

Вопросы, где были ошибки