Kafka partitions, offsets, consumer groups и rebalancing¶
Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.
Версии в источниках: 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]
Пошаговое объяснение¶
- Producer выбирает partition по контракту routing.
- Consumer получает assignment и читает records.
- Handler завершает durable effect.
- Commit фиксирует next offset только по завершённому префиксу этой partition.
- 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.