kafka connect: use a stable coordinator transactional id to fence stale coordinators - #18039
Open
twthorn wants to merge 2 commits into
Open
kafka connect: use a stable coordinator transactional id to fence stale coordinators#18039twthorn wants to merge 2 commits into
twthorn wants to merge 2 commits into
Conversation
…le coordinators Signed-off-by: Thomas Thornton <thomaswilliamthornton@gmail.com>
3 tasks
Signed-off-by: Thomas Thornton <thomaswilliamthornton@gmail.com>
Contributor
Author
|
@laskoviymishka could you review this when you get a free moment? Thanks! |
laskoviymishka
self-requested a review
September 10, 2026 09:30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #18038
Add support for coordinator fencing. This can prevent stale ("zombie") coordinators from committing stale consumer offsets.
Implementation
Currently, we generate a new UUID for every new coordinator. This means that the Kafka transaction we use trivially passes since no epoch fencing can be performed on the newly generated ID (e.g., between a stale or an up to date coordinator).
The change is to use a persistent transactional ID for the coordinator. We name this using the connect group ID which is unique to that connector. Then any leader change of that group will trigger Kafka to update the epoch of the transaction, and correctly fence stale coordinators. A stale coordinator will identify that it has been fenced, and exit the coordinator thread. We leave the worker task running and defer to Kafka Connect on determining its lifecycle.
Note: we introduced a in-memory monotonic increasing offset guard to make offsets monotonically increasing (values that are non-increasing are not committed). This was a tightly scoped fix to reduce the risk of a coordinator committing old offsets (which can cause data loss). However, it is theoretically possible that offsets could still be updated if an older coordinator wrote a higher offset than it last stored, but is less than another coordinator's written offset. The way to solve this and the canonical one in Kafka is with producer fencing. So we add the offset commit in its own transaction, and defer to kafka for epoch fencing.
Note: we also intentionally make the commit consumer offsets its separate transaction. It is outside the scope of this PR to refactor the offset transaction semantics (eg grouping the control topic offset write with the consumer offset commit). This delivers the minimal set of changes to have fenced consumer offset commits.
Testing
Used an integration test to reproduce this failure scenario first (ie a stale coordinator with an increasing offset but is older than another offset of a newer coordinator). Also added unit tests as well.
Related Work
In-memory monotonic offset guard:
Larger scoped coordinator refactor (PR is stale, has merge conflicts):
Related preventative setting offset reset strategy: