Kafka это распределённая платформа event streaming. Producer дописывает события в partition внутри topic, а consumer читает их по offset. Порядок гарантируется только внутри одной partition. Consumer group распределяет partitions между участниками, а разные группы читают один поток независимо. События не удаляются сразу после чтения и могут быть прочитаны повторно, пока действует retention.
Модель Kafka
Producer -> Topic -> Partition 0 -> Consumer group A
-> Partition 1 -> Consumer group A
-> Partition 2 -> Consumer group B
Основные сущности:
event / record: ключ, значение, timestamp и headers;
producer: публикует события;
topic: логическое имя потока;
partition: упорядоченный append-only log;
offset: позиция записи внутри partition;
broker: сервер Kafka;
consumer: читает события;
consumer group: группа потребителей, делящая работу;
replica: копия partition для отказоустойчивости.
Зачем нужны partitions
Partition решает две задачи:
позволяет распределять хранение и нагрузку по brokers;
позволяет обрабатывать поток параллельно.
Producer выбирает partition напрямую или через key. События с одинаковым key обычно попадают в одну partition, поэтому их порядок сохраняется относительно этого ключа.
Глобального порядка между разными partitions нет. Если бизнес требует последовательность OrderCreated -> PaymentCompleted -> OrderShipped, выбери ключ, который отправит события одного заказа в одну partition.
Consumer groups
В классической consumer group одна partition в конкретный момент назначается одному consumer. Поэтому количество активно работающих consumers не может эффективно превышать количество partitions.
Если consumers подключаются или отключаются, Kafka перераспределяет partitions. Это называется rebalance. Во время rebalance возможна пауза, а неправильная работа с offsets может привести к повторной обработке или пропуску.
Разные consumer groups независимы:
группа аналитики читает все заказы;
группа уведомлений читает те же события;
группа антифрода тоже читает тот же topic.
Offset и повторное чтение
Consumer получает записи начиная с offset и периодически сохраняет, до какой позиции он дошёл. Offset можно сдвинуть назад и повторно обработать старые события.
Критический момент: когда именно сохраняется offset.
Commit до обработки может дать потерю при падении.
Commit после обработки может дать дубль, если обработка завершилась, а commit не успел.
Поэтому consumer должен быть готов к повторной доставке и по возможности быть идемпотентным.
Delivery semantics
Семантика
Что означает
At most once
Возможна потеря, повторов нет
At least once
Потерю стараются исключить, возможны повторы
Exactly once
Эффект обработки должен возникнуть один раз в определённых границах
Kafka поддерживает idempotent producer и transactions. Но фраза "Kafka даёт exactly once" без контекста опасна. Гарантия зависит от настроек producer, consumer, isolation level и внешней системы, куда consumer записывает результат.
Если consumer создал платёж во внешней БД, Kafka transaction сама по себе не сделает эту внешнюю запись exactly once.
Retention и compacted topics
Kafka обычно хранит события по времени или объёму независимо от того, прочитаны они или нет.
Два важных режима:
обычный retention удаляет старые сегменты по политике;
log compaction сохраняет последнее известное значение для каждого key, хотя удаление старых версий происходит не мгновенно.
QA должен проверить поведение consumer, если нужное событие уже вышло за retention.
Репликация
Partition имеет leader и replicas. Producer и consumer работают с leader. Реплики синхронизируют log и могут принять роль leader после сбоя.
Проверяй:
replication factor;
количество in-sync replicas;
поведение при падении leader;
настройки acks;
допустимость записи при уменьшении ISR;
восстановление consumer после смены leader.
Чек-лист тестирования Kafka
Контракт события
обязательные поля присутствуют;
типы и ограничения соблюдены;
schema version понятна consumer;
новый producer совместим со старым consumer;
неизвестные поля не ломают обработку;
персональные данные не попали в topic без необходимости.
Маршрутизация и порядок
событие опубликовано в правильный topic;
key выбран по бизнес-сущности;
события одного key сохраняют порядок;
события без key распределяются ожидаемо;
количество partitions не ломает предположения consumer.
Дубли и идемпотентность
повтор одного event id не создаёт второй платёж или заказ;
retry producer не создаёт неожиданный эффект;
consumer корректно переживает падение до и после commit offset;
дедупликация имеет понятный срок хранения.
Ошибочные сообщения
сломанный JSON не останавливает всю partition навсегда;
неизвестная schema version обрабатывается явно;
poison message попадает в отдельный поток или фиксируется;
retry ограничен;
ошибка наблюдаема по метрикам и логам.
Нагрузка
растёт ли consumer lag;
хватает ли partitions для параллельности;
как batching влияет на latency;
не превышен ли максимальный размер record;
выдерживается ли всплеск producer traffic;
успевает ли consumer догнать поток после простоя.
Отказоустойчивость
падение broker;
restart consumer;
сетевой timeout;
rebalance;
временная недоступность внешней БД;
окончание retention;
повторная обработка диапазона offsets.
Наблюдаемость
Минимально полезные данные:
topic, partition и offset;
event id и business key;
consumer group;
consumer lag;
время публикации и время обработки;
correlation id;
количество retries;
причина отправки в dead-letter topic.
Без этих данных распределённый дефект превращается в гадание.
Вопросы на собеседовании
Где Kafka гарантирует порядок?
Внутри одной partition. Между partitions общего порядка нет.
Что будет, если consumers больше, чем partitions?
В классической consumer group часть consumers останется без назначенных partitions.
Чем offset отличается от event id?
Offset это позиция записи внутри конкретной partition. Event id является прикладным идентификатором события и может использоваться для дедупликации.
Может ли один event получить несколько consumers?
Внутри одной consumer group запись обрабатывает один участник. Разные groups получают поток независимо.
Kafka это очередь?
Она может решать похожие задачи, но модель ближе к сохраняемому распределённому log. Чтение не удаляет запись, а consumer управляет своей позицией.
Как тестировать at least once?
Имитировать сбой между бизнес-операцией и commit offset, затем убедиться, что повторная доставка не создаёт второй бизнес-эффект.
Главное запомнить
Topic делится на partitions.
Порядок существует только внутри partition.
Key влияет на partition и бизнес-порядок.
Offset принадлежит позиции чтения, а не бизнес-событию.
At least once требует идемпотентного consumer.
Consumer lag является главным сигналом отставания обработки.