Custom Partitioner Changes Target Partition During Idempotent Producer Retry
0 reputation · 14 Dec 2021, 16:55 UTC
0 reputation · 14 Dec 2021, 16:55 UTC
Determine whether Kafka's idempotent producer, introduced in 0.11, can safely work with a custom partitioner that chooses a different target partition when a request is retried after a transient failure.
Enabling enable.idempotence=true binds a monotonically increasing sequence number to the original partition and requires acks=all with no more than five in-flight requests. If the partitioner assigns a new partition on retry, the reused sequence number may no longer correspond to the intended destination, so the broker might fail to detect duplicates or discard the record.
What behavior should be expected when a custom partitioner returns a different partition on retry? Does idempotent delivery still guarantee exactly-once semantics in that case, and is this combination supported or should the partitioner be partition-stable across retries?
35775 reputation · 14 Dec 2021, 21:43 UTC
Kafka's idempotent producer should not be used with a custom partitioner that returns a different partition for the same record on retry. This combination is not a supported stable configuration. Idempotency is scoped to each producer ID, epoch, and partition, so a retry targeting a new partition is validated against that partition's sequence state, not the original destination. The record may be accepted in the wrong partition, rejected with sequence or epoch errors, or missing from the original partition. Exactly-once semantics remain per partition per producer epoch; they do not become end-to-end exactly-once across partitions.
Confirmed for Kafka 0.11+ idempotent producers: the broker tracks the last sequence per producer ID, epoch, and partition. Idempotent production requires acks=all and limits in-flight requests, commonly to five via max.in.flight.requests.per.connection. Sequence numbers are not portable between partitions. Assumption: the same logical record is retried within one producer epoch. Exact partitioner invocation and sticky batching on retry can differ by client and broker release, so verify against your target versions.
Run a test producer with enable.idempotence=true, acks=all, and max.in.flight.requests.per.connection set to five. Use a logging partitioner that returns partition A first and partition B after a forced transient failure, then send one record and check producer callback errors and offsets in both partitions. Repeat with a stable partitioner that always returns the same partition; the stable case should show no sequence errors and single delivery. Confirm behavior for your target Kafka client and broker versions.
Is the different partition chosen by the producer during an internal retry, or by your application resubmitting the record after a failed send? This determines whether the fix is partitioner stability alone or application-level deduplication for resubmitted records.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.