Kafka transactions и idempotent producers¶
Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.
Версии в источниках: Kafka/Connect/Streams 4.1, Debezium 3.3, Flink 1.20.3, Spark 4.0.1 и Airflow 3.1 либо явно названная система. Непроверенные вопросы и ограничения runtime — в журнале (архив рабочего проекта).
Механизм¶
Idempotence подавляет protocol retry duplicates с producer ID/epoch/sequence. Kafka transaction связывает writes нескольких partitions/topics и поддерживаемые group offsets. Это разные уровни: idempotence не dedup business ID, transaction не включает произвольную внешнюю БД.
flowchart TB
Input[Kafka records] --> Begin[Begin transaction]
Begin --> Output[Produce Kafka output]
Output --> Offsets[Add input group offsets]
Offsets --> Commit[Commit or abort]
Commit --> Visible[read_committed visibility]
Output -. outside boundary .-> HTTP[External HTTP effect]
Пошаговое объяснение¶
init_transactions получает transactional identity и fencing → begin_transaction → produce derived records → send_offsets_to_transaction с group metadata → commit_transaction. Downstream read_committed читает committed records. При abort input offsets не продвигаются как successful transaction, data не публикуется как committed.
Failure scenarios и recovery¶
Crash/timeout после commit request даёт неопределённость клиента; library error flags определяют retry/abort/fatal actions. Новый active producer с тем же transactional.id fence старый. Разные независимые writers не должны случайно делить этот ID; recovery одного logical writer требует стабильной identity.
Trade-offs и эксплуатация¶
Transactions добавляют coordinator state, markers, timeout/fencing и задержку visibility. Длительная open transaction удерживает stable visibility. Exactly-once Kafka pipeline не предотвращает repeated HTTP charge, исполненный до abort; outbox/idempotent endpoint решают иной boundary.
Практический пример¶
Python producer показывает basic/idempotent/transactional modes. Специально повторённая строка input остаётся новым business send, даже при enable.idempotence=true.
Типичные ошибки проектирования¶
Смешивать source/state/sink boundaries, скрывать failed records и неопределённый исход timeout; применять retry без identity/version и retention contract. Конкретные ограничения разобраны выше.
Вопросы на собеседовании¶
acks=all равно transaction? Нет, acknowledgement durability и atomic group publication различаются.
Почему aborted SQL effect не исчез? SQL не участвовал в Kafka transaction.
Практические упражнения¶
Составьте matrix commit/abort/fenced/unknown response. Для каждого опишите безопасное действие клиента без выдуманного глобального EOS.