Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KAFKA-13988: Enable replicating from latest offset with MirrorMaker 2 #14567

Merged
merged 3 commits into from
Dec 4, 2023

Conversation

C0urante
Copy link
Contributor

Jira

Based off of #13905, which itself appears to be based off of #12358. The only changes applied here are the ones proposed during review of #13905.

This PR tweaks how the MirrorSourceTask class interacts with its consumer on startup. With this change, instead of manually seeking to offset 0 when no committed offset for a topic partition is found, no seek is performed at all. This allows users to configure MM2 to begin replicating from the ends of topics (as opposed to the beginning, which is and remains the default behavior) by configuring its consumer with auto.offset.reset set to latest.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@C0urante C0urante changed the title KAFKA-13988: Enable replicating from latest with MirrorMaker 2 KAFKA-13988: Enable replicating from latest offset with MirrorMaker 2 Oct 17, 2023
Copy link
Contributor

@hudeqi hudeqi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, Chris. Thanks for this PR, we have also made similar functions based on version 2.8.1. Here I left a minor comment.

log.info("Starting with {} previously uncommitted partitions.", topicPartitionOffsets.values().stream()
.filter(this::isUncommitted).count());

log.trace("Seeking offsets: {}", topicPartitionOffsets.entrySet().stream()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topicPartitionOffsets here maybe not a correct offset for committed offsets(actually needs to plus 1), right? So the log here may be misleading. I think the line 285 is correct. Maybe the two places can retain one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Considering they're both at TRACE level, I think it's fine to remove this one.

Copy link
Contributor

@fvaleri fvaleri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @C0urante. I was also tracking this one. Left few minor comments.

void initializeConsumer(Set<TopicPartition> taskTopicPartitions) {
Map<TopicPartition, Long> topicPartitionOffsets = loadOffsets(taskTopicPartitions);
consumer.assign(topicPartitionOffsets.keySet());
log.info("Starting with {} previously uncommitted partitions.", topicPartitionOffsets.values().stream()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
log.info("Starting with {} previously uncommitted partitions.", topicPartitionOffsets.values().stream()
log.debug("Found {} uncommitted partitions.", topicPartitionOffsets.values().stream()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO the existing log is fine--can you elaborate on why you believe this change is necessary? Logging at INFO level seems okay since this should happen once per task lifecycle, and "Starting with" also seems warranted given that this should only occur during MirrorSourceTask::start.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just thought that we already have an info level message at the end of MirrorSourceTask::start and this message was not that useful, but I don't have a strong opinion, so I'm fine with leaving it as it is.

@@ -302,6 +320,10 @@ private static int byteSize(byte[] bytes) {
}
}

private boolean isUncommitted(Long offset) {
return offset == null || offset < 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like unwrapOffset takes care of the null check. We can simply use the primitive type here and check equal to -1L (it can't have any other value). Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked this suggestion initially and played around with changing MirrorUtils::unwrapOffset to return a primitive long type, but we end up being forced to convert offsets back to boxed Long types when using them to populate a Map<TopicPartition, Long> in MirrorSourceTask::loadOffsets.

IMO, without the ability to guarantee via the type system that values are non-null, we should try to handle them in cases like this, so I'd prefer to keep it as-is. Let me know if there are any implications I'm missing that might still warrant a direct comparison to -1L, though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Thanks for exploring that suggestion.

@hudeqi
Copy link
Contributor

hudeqi commented Oct 19, 2023

LGTM, thanks for this PR!

Copy link
Contributor

@fvaleri fvaleri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @C0urante, LGTM. Thanks.

void initializeConsumer(Set<TopicPartition> taskTopicPartitions) {
Map<TopicPartition, Long> topicPartitionOffsets = loadOffsets(taskTopicPartitions);
consumer.assign(topicPartitionOffsets.keySet());
log.info("Starting with {} previously uncommitted partitions.", topicPartitionOffsets.values().stream()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just thought that we already have an info level message at the end of MirrorSourceTask::start and this message was not that useful, but I don't have a strong opinion, so I'm fine with leaving it as it is.

@@ -302,6 +320,10 @@ private static int byteSize(byte[] bytes) {
}
}

private boolean isUncommitted(Long offset) {
return offset == null || offset < 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Thanks for exploring that suggestion.

@C0urante
Copy link
Contributor Author

C0urante commented Dec 4, 2023

@gharris1727 @showuon @mimaison would any of you have time to take a look? Hoping we can get this one merged in time for 3.7.0.

Copy link
Contributor

@gharris1727 gharris1727 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks @C0urante for taking this over the finish line.

Also thanks to @Justinwins and @blacktooth for the earlier PRs, @yuz10 for review, and @electrical for stitching together the history of this change.

@C0urante
Copy link
Contributor Author

C0urante commented Dec 4, 2023

Thanks Greg!

@C0urante C0urante merged commit a83bc2d into apache:trunk Dec 4, 2023
1 check failed
@C0urante C0urante deleted the kafka-13988 branch December 4, 2023 21:38
C0urante added a commit that referenced this pull request Dec 4, 2023
ex172000 pushed a commit to ex172000/kafka that referenced this pull request Dec 15, 2023
gaurav-narula pushed a commit to gaurav-narula/kafka that referenced this pull request Jan 24, 2024
yyu1993 pushed a commit to yyu1993/kafka that referenced this pull request Feb 15, 2024
clolov pushed a commit to clolov/kafka that referenced this pull request Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants