Перейти к содержанию

Kafka

Apache Kafka — это распределенная платформа для передачи, хранения и чтения событий.

Проще всего думать о Kafka так:

  • producer отправляет событие;
  • Kafka кладет его в распределенный журнал;
  • consumer читает это событие по offset;
  • разные consumer groups могут читать одни и те же события независимо друг от друга.

Kafka особенно полезна там, где нужно:

  • развязать сервисы по времени;
  • перейти от синхронных вызовов к event-driven взаимодействию;
  • буферизовать нагрузку;
  • собирать поток событий, логов, метрик;
  • обрабатывать один и тот же поток несколькими независимыми системами.

Как правильно думать о Kafka

Главная идея:

Kafka ближе к распределенному append-only log, чем к классической очереди.

То есть:

  • сообщения не "исчезают" сразу после чтения;
  • consumer сам хранит позицию чтения;
  • один и тот же поток можно читать повторно;
  • несколько групп могут читать один и тот же topic независимо;
  • Kafka хорошо подходит для событий и потоковой обработки.

Минимальная ментальная модель:

Producer -> Topic -> Partition -> Offset -> Consumer Group -> Consumer

Или еще проще:

Kafka = большой распределенный журнал,
в который сервисы пишут события,
а другие сервисы читают их с нужного места.

Зачем Kafka нужна на практике

Пример без Kafka:

Order Service -> Payment Service
Order Service -> Inventory Service
Order Service -> Notification Service
Order Service -> Analytics Service

Проблемы:

  • много синхронных вызовов;
  • сильная связанность;
  • если один downstream недоступен, весь сценарий может деградировать;
  • сложно масштабировать потребителей независимо;
  • повторно использовать один и тот же поток данных неудобно.

Пример с Kafka:

Order Service -> публикует OrderCreated в Kafka

Payment Service       читает OrderCreated
Inventory Service     читает OrderCreated
Notification Service  читает OrderCreated
Analytics Service     читает OrderCreated

Плюсы:

  • producer не обязан знать всех потребителей;
  • сервисы слабее связаны;
  • можно обрабатывать события асинхронно;
  • один поток событий используют много разных систем;
  • потребителей можно масштабировать отдельно друг от друга.

Когда Kafka действительно подходит

Kafka полезна, когда:

  • событий много и они идут непрерывным потоком;
  • нужно хранить поток какое-то время и уметь его перечитывать;
  • один producer должен кормить сразу несколько систем;
  • важна высокая пропускная способность;
  • надо выровнять пики нагрузки;
  • есть event-driven архитектура;
  • нужна интеграция между микросервисами, аналитикой, CDC, ETL.

Kafka подходит хуже, когда:

  • нужна простая очередь "взял задачу и удалил";
  • сообщений мало и сложность Kafka не окупается;
  • нужен request/response с быстрым синхронным ответом;
  • важна сложная маршрутизация сообщений по правилам, а не log-based модель;
  • нужен точный workflow-оркестратор, а не транспорт событий.

Основные понятия Kafka

Broker

Broker — это сервер Kafka.

Kafka-кластер обычно состоит из нескольких broker'ов. Они вместе:

  • принимают сообщения от producer'ов;
  • хранят partition'ы topic'ов;
  • отдают данные consumer'ам;
  • реплицируют данные между собой;
  • участвуют в failover и выборе лидеров partition'ов.

Topic

Topic — это логическая категория событий.

Примеры:

  • orders.created
  • payments.completed
  • users.registered

Важно:

  • topic — это не один файл и не одна очередь;
  • topic обычно разбит на несколько partition;
  • именно через topic producer и consumer логически "договариваются", куда писать и что читать.

Record / Message

Одна запись в Kafka обычно содержит:

  • key
  • value
  • timestamp
  • headers

Пример:

{
  "key": "order-123",
  "value": {
    "orderId": "order-123",
    "userId": "u-1",
    "amount": 4500
  }
}

Практически:

  • key часто определяет partition;
  • value — полезная нагрузка;
  • headers — служебные метаданные;
  • timestamp нужен для времени события или времени записи.

Partition

Partition — это часть topic.

Один topic может быть разбит на несколько partition.

Это нужно для:

  • масштабирования хранения;
  • параллельной обработки;
  • распределения нагрузки между broker'ами.

Пример:

Topic orders.created
  partition-0
  partition-1
  partition-2

Самая важная мысль:

Kafka гарантирует порядок только внутри одной partition.

То есть:

  • внутри partition-0 порядок сохраняется;
  • между partition-0 и partition-1 глобального порядка нет.

Отсюда сразу следует:

  • хочешь порядок для сущности orderId=123 -> все события этой сущности должны попадать в одну partition;
  • хочешь больше параллелизма -> увеличиваешь число partition;
  • но чем больше partition, тем больше operational complexity.

Offset

Offset — это позиция записи внутри конкретной partition.

Например:

partition-0:
offset 0
offset 1
offset 2
offset 3

Offset нужен, чтобы consumer понимал:

  • до какого места он дочитал;
  • откуда продолжить после рестарта;
  • какие записи можно перечитать;
  • где зафиксирована обработанная позиция.

Важно:

  • offset уникален только внутри partition;
  • offset не общий для всего topic;
  • consumer хранит не "список обработанных сообщений", а позицию чтения.

Producer

Producer — это приложение, которое отправляет сообщения в Kafka.

Producer решает:

  • в какой topic писать;
  • какой key использовать;
  • нужно ли ждать подтверждения записи;
  • как обрабатывать retry и дубликаты.

Примеры producer'ов:

  • Order Service публикует OrderCreated;
  • Payment Service публикует PaymentCompleted;
  • frontend или gateway публикует пользовательские события;
  • Debezium публикует события изменений из БД.

Consumer

Consumer — это приложение, которое читает сообщения из Kafka.

Consumer:

  • подписывается на topic;
  • читает записи по partition;
  • обрабатывает их;
  • коммитит offset, когда считает позицию безопасной.

Примеры consumer'ов:

  • Inventory Service читает OrderCreated;
  • Notification Service читает UserRegistered;
  • аналитический сервис читает клики и события продукта.

Consumer Group

Consumer Group — это группа consumer'ов, которые читают topic совместно.

Правило:

  • внутри одной consumer group каждая partition в обычном consumer group назначается только одному consumer;
  • разные consumer groups читают один и тот же topic независимо.

Пример:

Есть topic orders.created с 3 partition.

Группа inventory-group:

  • consumer-1 читает partition-0
  • consumer-2 читает partition-1
  • consumer-3 читает partition-2

Группа analytics-group:

  • читает те же события независимо от inventory-group

Это значит:

  • одна group = горизонтальное масштабирование одного logical consumer;
  • разные groups = pub/sub между разными системами.

Как Kafka работает целиком

Сценарий end-to-end:

  1. Producer подключается к Kafka через bootstrap.servers.
  2. Producer получает metadata: какие есть broker'ы, topics, partition leaders.
  3. Producer выбирает partition:
  4. явно;
  5. по key;
  6. или без key по встроенной стратегии.
  7. Producer отправляет запись лидеру нужной partition.
  8. Leader append'ит запись в лог partition.
  9. Followers реплицируют эту запись.
  10. Когда запись считается committed, consumer сможет ее увидеть.
  11. Consumer читает запись по offset.
  12. После успешной обработки consumer коммитит новый offset.

Короткая схема:

Producer
  -> leader partition append
  -> replication to followers
  -> message committed
  -> consumer fetch
  -> processing
  -> offset commit

Самые важные свойства Kafka

1. Сообщение не удаляется из-за чтения

Kafka не работает по модели:

прочитал -> удалил

Kafka работает по модели:

записал в лог -> храним по retention policy -> consumers читают своим темпом

То есть consumer не "владеет" сообщением. Он просто двигает свой offset.


2. Порядок есть только внутри partition

Это одна из самых частых ошибок в понимании Kafka.

Нельзя рассчитывать на:

  • глобальный порядок в topic;
  • порядок между разными partition;
  • порядок между разными consumer groups.

Можно рассчитывать только на:

  • порядок записей внутри одной partition.

3. Параллелизм ограничен количеством partition

Если у topic 3 partition и одна consumer group, то одновременно этот topic в стандартной consumer group сможет читать не больше 3 активных consumer'ов.

То есть:

  • 3 partition + 10 consumers -> реально работают максимум 3;
  • 20 partition + 3 consumers -> у каждого consumer будет по несколько partition.

4. Kafka хорошо умеет replay

Consumer может:

  • начать читать сначала;
  • перемотать offset назад;
  • завести новую consumer group и перечитать весь поток.

Это одно из главных отличий Kafka от классических брокеров сообщений.


5. Kafka дает durability и throughput, но не снимает ответственность с приложения

Kafka не решает автоматически:

  • идемпотентность бизнес-обработки;
  • дедупликацию внешних side effect'ов;
  • эволюцию схем данных;
  • корректную retry policy;
  • выбор key и partition strategy.

Если эти решения плохие, даже хороший Kafka-кластер не спасет архитектуру.


Что чаще всего нужно помнить на собеседовании и в работе

  • Kafka = distributed append-only log.
  • Topic разбит на partition.
  • Порядок гарантирован только внутри partition.
  • Offset — это позиция записи внутри partition.
  • Consumer group нужна для совместного чтения и балансировки нагрузки.
  • Сообщение не удаляется после чтения consumer'ом.
  • Несколько consumer groups читают один и тот же поток независимо.
  • acks, replication factor и min.insync.replicas влияют на durability.
  • Без идемпотентности и аккуратного offset commit легко получить дубликаты.
  • Exactly-once в Kafka имеет узкие границы и не равна "магически без дублей везде".

Какие файлы читать дальше

  • Architecture — как устроен кластер, leader/follower, ISR, failover
  • Producers & Consumers — запись, чтение, offset commit, delivery semantics
  • Storage & Semantics — лог, retention, compaction, replay, ordering
  • Design Patterns — outbox, retries, DLQ, schema/versioning, Kafka vs queue
  • Operations — мониторинг, sizing, продовые ошибки и практические настройки