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

Kafka partitions, offsets, consumer groups и rebalancing

Глубокие темы · Раздел03

Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.

Версии в источниках: Kafka/Connect/Streams 4.1, Debezium 3.3, Flink 1.20.3, Spark 4.0.1 и Airflow 3.1 либо явно названная система. Непроверенные вопросы и ограничения runtime — в журнале (архив рабочего проекта).

Механизм

Partition — единица ordered log и обычного group assignment. Offset адресует позицию внутри partition; он не global sequence и может иметь gaps из-за compaction/transactions. Group committed offset — next position для восстановления, fetch position — текущая позиция клиента.

flowchart TB
  Partition --> Assign[Group assignment]
  Assign --> Poll[Fetch position]
  Poll --> Effects[Complete per-partition prefix]
  Effects --> Commit[Commit next safe offset]
  Commit --> Rebalance[Restore after reassignment]

Пошаговое объяснение

  1. Producer выбирает partition по контракту routing.
  2. Consumer получает assignment и читает records.
  3. Handler завершает durable effect.
  4. Commit фиксирует next offset только по завершённому префиксу этой partition.
  5. Rebalance передаёт ownership, новый member начинает с committed position.

Failure scenarios и recovery

Если poll отдал batch, а records исполняются параллельно, commit max(offset) может пропустить незавершённый ранний record. Нужен contiguous completed frontier per partition. Revoke/assignment callbacks зависят от classic/cooperative/new consumer protocol. Heartbeat не разрешает обрабатывать partition бесконечно вне max.poll constraints.

Trade-offs и эксплуатация

Больше partitions даёт parallelism и overhead. Больше consumers, чем assigned partitions, не ускоряет стандартный group processing. Изменение partition count меняет key placement; для непрерывного per-aggregate order нужна migration barrier/routing version.

Практический пример

Запустите manual commit consumer. Он выполняет одну запись синхронно, коммитит после durable projection и не использует опасное commit-latest при незавершённом batch.

Типичные ошибки проектирования

Смешивать source/state/sink boundaries, скрывать failed records и неопределённый исход timeout; применять retry без identity/version и retention contract. Конкретные ограничения разобраны выше.

Вопросы на собеседовании

Почему commit offset N+1, а не N? Это позиция следующего чтения после N.

Как commit после revoke? Он может быть отклонён; уже durable effect должен пережить replay идемпотентно.

Практические упражнения

Нарисуйте offsets10/11/12, где11 ещё не обработан. Укажите безопасный committed frontier и действия при revoke.

Дополнительные источники