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-4743: Add Reset Consumer Group Offsets tooling [KIP-122] #2624

Closed
wants to merge 30 commits into from

Conversation

jeqo
Copy link
Contributor

@jeqo jeqo commented Mar 1, 2017

No description provided.

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1929/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1932/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1930/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1932/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1935/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented Mar 1, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1933/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1945/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1948/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1946/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/1948/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/1951/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented Mar 2, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/1949/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented May 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/3686/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented May 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/3692/
Test FAILed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented May 9, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/3682/
Test PASSed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented May 10, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.10/3696/
Test FAILed (JDK 7 and Scala 2.10).

@asfbot
Copy link

asfbot commented May 10, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.11/3702/
Test PASSed (JDK 8 and Scala 2.11).

@asfbot
Copy link

asfbot commented May 10, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/3692/
Test FAILed (JDK 8 and Scala 2.12).

Copy link
Contributor

@ijuma ijuma left a comment

Choose a reason for hiding this comment

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

Thanks for the PR, I had a quick look and left some comments (note that I didn't do a proper review).

val consumer = getConsumer()
consumer.assign(List(topicPartition).asJava)
consumer.seekToBeginning(List(topicPartition).asJava)
val logStartOffset = consumer.position(topicPartition)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't you use beginningOffsets?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it look something like this right?

      val offsets = consumer.beginningOffsets(List(topicPartition).asJava)
      val logStartOffset = offsets.get(topicPartition)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes.

protected def getLogTimestampOffset(topicPartition: TopicPartition, timestamp: Long): LogOffsetResult = {
val consumer = getConsumer()
consumer.assign(List(topicPartition).asJava)
val offsetForTimestamp = Option(consumer.offsetsForTimes(Map(topicPartition -> timestamp.asInstanceOf[java.lang.Long]).asJava))
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of asInstanceOf, you can do timestamp: java.lang.Long which is checked by the compiler.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, why are we wrapping the result of offsetsForTimes in an Option? It can never be null.

package unit.kafka.admin

import java.io.{BufferedWriter, File, FileWriter}
import java.time.{Duration, LocalDateTime, ZonedDateTime}
Copy link
Contributor

Choose a reason for hiding this comment

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

We still support Java 7, so we cannot use these classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, didn't know that KIP-118 was moved to 0.12. ok, I will check it.

@asfbot
Copy link

asfbot commented May 12, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/3809/
Test PASSed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented May 12, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.11/3821/
Test PASSed (JDK 7 and Scala 2.11).

@asfbot
Copy link

asfbot commented May 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.11/3924/
Test PASSed (JDK 7 and Scala 2.11).

@asfbot
Copy link

asfbot commented May 15, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/3913/
Test PASSed (JDK 8 and Scala 2.12).

@hachikuji
Copy link
Contributor

@jeqo I think there is still some confusing terminology in the current patch. I submitted a PR to fix this along with a few simplifications: jeqo#1. If it looks good, can you merge it here?

A few terminology corrrections and simplifications
@asfbot
Copy link

asfbot commented May 16, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk7-scala2.11/3982/
Test PASSed (JDK 7 and Scala 2.11).

@asfbot
Copy link

asfbot commented May 16, 2017

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/kafka-pr-jdk8-scala2.12/3970/
Test PASSed (JDK 8 and Scala 2.12).

(topicPartition, resetPlan(topicPartition))
else null
}.toMap
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems this case isn't actually allowed by the command. Maybe we can raise an IllegalArgumentException to make that explicit.

Copy link
Contributor

Choose a reason for hiding this comment

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

My mistake. It is allowed, but I'm wondering if it is useful.

val topics = opts.options.valuesOf(opts.topicOpt).asScala
parseTopicPartitionsToReset(topics)
} else {
CommandLineUtils.printUsageAndDie(opts.parser, "One of the reset scopes should be defined: --all-topics, --topic.")
Copy link
Contributor

Choose a reason for hiding this comment

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

If you provide a reset csv file, isn't the scope unnecessary?

}

private def prepareOffsetsToReset(groupId: String, partitionsToReset: Iterable[TopicPartition]): Map[TopicPartition, OffsetAndMetadata] = {
if (opts.options.has(opts.resetToOffsetOpt)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably need to check that the provided offset is in range as we do for the shift option. Same for the CSV case.

partitionsToReset.map { topicPartition =>
currentCommittedOffsets.get(topicPartition).map { offset =>
(topicPartition, new OffsetAndMetadata(offset))
}.orNull
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guilty for a bug here. Instead of .orNull, it should be .getOrElse((topicPartition, null)). Sorry!

Copy link
Contributor

@hachikuji hachikuji May 17, 2017

Choose a reason for hiding this comment

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

In fact, now that I'm thinking about it, there are a lot of cases in here where we return null when we don't know what offset to use. If that doesn't raise an NPE in toMap, it will probably raise one in commitSync. We probably need to filter out all partitions like this. Alternatively, maybe we could just raise an exception if we hit one of these cases? I feel it would be a little unsafe to go through with the offset commit with only some of the expected partitions.

@@ -566,10 +801,19 @@ object ConsumerGroupCommand extends Logging {
CommandLineUtils.checkRequiredArgs(parser, options, groupOpt)
if (options.has(deleteOpt) && !options.has(groupOpt) && !options.has(topicOpt))
CommandLineUtils.printUsageAndDie(parser, "Option %s either takes %s, %s, or both".format(deleteOpt, groupOpt, topicOpt))
if (options.has(resetOffsetsOpt))
Copy link
Contributor

Choose a reason for hiding this comment

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

If we assert that at least one of allResetOffsetScenarioOpts is provided, then we don't need the weird case above where we reset to the current offsets.

AdminUtils.createTopic(zkUtils, topic1, 1, 1)

val format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
val checkpoint = new Date()
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this is unused


@Test
def testResetOffsetsByDurationToEarliest() {
val cgcArgs = Array("--bootstrap-server", brokerList, "--reset-offsets", "--group", group, "--all-topics", "--by-duration", "PT0.1S", "--execute")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: it's easier to read this when you put the arguments on separate lines like you did for some of the test cases.

Copy link
Contributor

@hachikuji hachikuji left a comment

Choose a reason for hiding this comment

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

@jeqo Thanks for the patch. I'm going to go ahead and merge this as is. I've created https://issues.apache.org/jira/browse/KAFKA-5266 for the additional improvements I suggested. If you have time, I would appreciate if you would pick that up.

@asfgit asfgit closed this in 2181ae7 May 17, 2017
@jeqo
Copy link
Contributor Author

jeqo commented May 18, 2017

@hachikuji Cool, I will check it :) Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants