Skip to content

Comments

KAFKA-5358: Consumer perf tool should count rebalance time.#3188

Closed
huxihx wants to merge 15 commits intoapache:trunkfrom
huxihx:KAKFA-5358
Closed

KAFKA-5358: Consumer perf tool should count rebalance time.#3188
huxihx wants to merge 15 commits intoapache:trunkfrom
huxihx:KAKFA-5358

Conversation

@huxihx
Copy link
Contributor

@huxihx huxihx commented Jun 1, 2017

Added 'join.group.ms' for new consumer to calculate the time of joining group.

@hachikuji Please review the PR. Thanks.

Added 'join.group.ms' for new consumer to calculate the time of joining group.
@asfbot
Copy link

asfbot commented Jun 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/4700/
Test PASSed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented Jun 1, 2017

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

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.

Thanks for picking this up so quickly. Left a couple comments.

if (!config.hideHeader) {
if (!config.showDetailedStats)
println("start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec")
println(s"start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec${if (!config.useOldConsumer) ", join.group.ms" else ""}")
Copy link
Contributor

Choose a reason for hiding this comment

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

A couple suggestions:

  1. Maybe the name could be total.rebalance.time or something like that?
  2. Perhaps additionally we could report total.fetch.time?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does total.fetch.time include total.rebalance.time ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's say they are independent. We could also include total.time, but perhaps no need.


totalMessagesRead.set(messagesRead)
totalBytesRead.set(bytesRead)
joinTime.set(joinEnd - joinStart)
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should allow for the possibility that we have more than one rebalance?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently, this perf tool does not support multiple consumer instances in one consumer group for new consumer, so is it possible that there will be more than one rebalance?

Copy link
Contributor

Choose a reason for hiding this comment

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

The user can pass the groupId as a parameter, so seems possible, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

And further rebalances may be possible anyway depending on the state of the brokers.

2. Added `total.fetch.time`
3. Add support to count total time for multiple rebalances
@asfbot
Copy link

asfbot commented Jun 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/4780/
Test FAILed (JDK 8 and Scala 2.12).

@asfbot
Copy link

asfbot commented Jun 2, 2017

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

var lastBytesRead = 0L
var lastMessagesRead = 0L
var joinStart = 0L
var totalRebalanceTimeExceptTheFirst = 0L
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 not sure I understand what you're trying to do here. Why not just count all rebalances?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The time for the first rebalance happens before the fetch but the rest would happen during the fetch. That's why I removed the total time of other rebalances from the total fetch time. Does it make any sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hachikuji What do you think of the comment above?

Copy link
Contributor

Choose a reason for hiding this comment

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

I still don't understand why you want to treat the first rebalance specially. Can you elaborate please? Intuitively, I expect that we count the total time for the test and subtract the total rebalance time to get the fetch time. Is there anything wrong with that?

@huxihx
Copy link
Contributor Author

huxihx commented Jun 6, 2017

@hachikuji yes, you are right. I complicated the issue. Addressed the comments and please review again. Thanks.

@asfbot
Copy link

asfbot commented Jun 6, 2017

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

@asfbot
Copy link

asfbot commented Jun 6, 2017

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

@huxihx
Copy link
Contributor Author

huxihx commented Jun 7, 2017

@hachikuji Please take some time to review. Thanks

consumerConnector.shutdown()
}
val elapsedSecs = (endMs - startMs) / 1000.0
fetchTimeInMs.set((endMs - startMs) - fetchTimeInMs.get)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you probably mean to subtract joinGroupTimeInMs?

@huxihx
Copy link
Contributor Author

huxihx commented Jun 7, 2017

Thanks for the comments and sorry for the typo. Please review again.

@asfbot
Copy link

asfbot commented Jun 7, 2017

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

@asfbot
Copy link

asfbot commented Jun 7, 2017

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

@@ -98,10 +101,17 @@ object ConsumerPerformance {
consumerConnector.shutdown()
}
val elapsedSecs = (endMs - startMs) / 1000.0
Copy link
Contributor

@hachikuji hachikuji Jun 7, 2017

Choose a reason for hiding this comment

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

I think the main point of this patch is to compute the throughput statistics based only on the time spent fetching, so maybe we can move this below and just use fetchTimeInMs.get / 1000.0? We could also report MB.sec as two separate values: total.MB.sec which uses the total time, and fetch.MB.sec which uses only the fetch time. Similarly for nMsg.sec.

2. Ditto for `nMsg.sec`
3. Refined output format
@huxihx
Copy link
Contributor Author

huxihx commented Jun 8, 2017

@hachikuji Refined the code to address your comments. A sample output is as below:
image
Does it look good now?

@asfbot
Copy link

asfbot commented Jun 8, 2017

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

@asfbot
Copy link

asfbot commented Jun 8, 2017

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

@huxihx
Copy link
Contributor Author

huxihx commented Jun 11, 2017

@hachikuji Could you take some time to review this PR? Thanks.

@hachikuji
Copy link
Contributor

@huxihx Yes, will get to it early this week. Sorry for the delay

@huxihx
Copy link
Contributor Author

huxihx commented Jun 16, 2017

@hachikuji Hello, did you get any chances to review this PR? Thanks.

@asfgit
Copy link

asfgit commented Jun 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/5366/
Test PASSed (JDK 8 and Scala 2.12).

@asfgit
Copy link

asfgit commented Jun 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/5381/
Test PASSed (JDK 7 and Scala 2.11).

config.dateFormat.format(startMs), config.dateFormat.format(endMs), totalMBRead,
totalMBRead / elapsedSecs, totalMessagesRead.get, totalMessagesRead.get / elapsedSecs))
} else {
println("---- performance test result ----")
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems unnecessary to make major changes to the output. Why don't we just keep the current format and add the additional fields? I thought the old patch did this and it seemed fine.

@asfgit
Copy link

asfgit commented Aug 9, 2017

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

@asfgit
Copy link

asfgit commented Aug 9, 2017

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

@asfgit
Copy link

asfgit commented Aug 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/6640/
Test PASSed (JDK 8 and Scala 2.12).

@huxihx
Copy link
Contributor Author

huxihx commented Aug 9, 2017

@hachikuji Please review the patch. Thanks.

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.

Left a couple more comments.

def testHeaderMatchBody(): Unit = {
Console.withOut(outContent) {
ConsumerPerformance.printHeader(true)
ConsumerPerformance.printHeader(true, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please provide parameter names. Also, let's add additional test cases so that we are covering all of the variations: detailed=true/false, consumer=old/new.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please address this comment.

s"${if (!useOldConsumer) ", rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec" else ""}"
)
} else {
println("time, threadId, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason we don't include the new fields in the "detailed" view?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the detailed view, can we safely think fetch.time.ms is always equal to elapsedMs in printProgressMessage? If yes, then the new fields fetch.MB.sec and fetch.nMsg.sec will always be equal to the existing ones MB.sec and nMsg.sec respectively, so that's why I did not have those new fields included in the detailed view. Does it make any sense?

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 not sure I follow. The fetch time is always equal to the total time minus the join group time. Can we not compute that periodically?

val consumerTimeout = new AtomicBoolean(false)
var metrics: mutable.Map[MetricName, _ <: Metric] = null
val joinGroupTimeInMs = new AtomicLong(0)
val fetchTimeInMs = new AtomicLong(0)
Copy link
Contributor

Choose a reason for hiding this comment

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

There doesn't appear to be any reason for fetchTimeInMs to be an AtomicLong. We can use a regular long and just initialize it below.

@huxihx
Copy link
Contributor Author

huxihx commented Aug 17, 2017

@hachikuji Thanks for the comments. Please review again.

@asfgit
Copy link

asfgit commented Aug 17, 2017

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

@asfgit
Copy link

asfgit commented Aug 17, 2017

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

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.

Thanks for the updates. A few more comments.

var metrics: mutable.Map[MetricName, _ <: Metric] = null
val joinGroupTimeInMs = new AtomicLong(0)
val fetchTimeInMs = new AtomicLong(0)
var fetchTimeInMs = 0L
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't need to be a var. We can just initialize it below, right?

@Test
def testHeaderMatchBody(): Unit = {
def testDetailedHeaderMatchBody(): Unit = {
testHeaderMatchContent(true, false, 2, () => ConsumerPerformance.printProgressMessage(1, 1024 * 1024, 0, 1, 0, 0, 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add parameter names for the two booleans?

joinTimeOpt match {
case Some(joinTime) =>
val fetchTimeMs = endMs - beginTime.getOrElse(startMs) - joinTime
println(", %d, %d, %.4f, %.4f".format(joinTime, fetchTimeMs, (bytesRead * 1.0 / (1024 * 1024) / (fetchTimeMs / 1000.0)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Now we're printing two lines in every call to printProgressMessage? Shouldn't we just include the additional information into one message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hachikuji The new-added fields are within the same line since I changed the first println to print. Am I doing right?

@huxihx
Copy link
Contributor Author

huxihx commented Aug 21, 2017

@hachikuji Thanks for your comments. Already addressed your comment 1 and 3. About comment 2, seems I already changed println to print so the new-added fields are also within the same line. Please review again.

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.

Thanks for the updates. Two more comments.

if (config.showDetailedStats)
printProgressMessage(0, bytesRead, lastBytesRead, messagesRead, lastMessagesRead, lastReportTime, currentTimeMillis, config.dateFormat)
printProgressMessage(0, bytesRead, lastBytesRead, messagesRead, lastMessagesRead,
lastReportTime, currentTimeMillis, config.dateFormat, Some(testStartTime), Some(joinTime.get))
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. There seems to be no reason for testStartTime to be an Option.
  2. Why do we call get on joinTime and rewrap it instead of just passing it through?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since joinTime is an AtomicLong, and printProgressMessage expects an Option, that's why I used Some(joinTime.get) here.
For old consumers, there is no join time, so printProgressMessage exposes an Option here. Does it make any senses?

endMs: Long,
dateFormat: SimpleDateFormat) = {
dateFormat: SimpleDateFormat,
beginTime: Option[Long] = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a little weird that we have both a startTime and a beginTime. I think the reason is that beginTime is computed from the start of the test, but startTime is computed after the first rebalance. However, now that we are calculating the rebalance time separately, I wonder if we still need to maintain this distinction. Maybe we can just use the test start time for both cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

startTime changes in each round of printProgressMessage but beginTime does not change after a test begins. printProgressMessage must use startTime to calculate TPS in a single call.

However, we also need to pass through beginTime which does not change after perf test gets started. It is used to calculate the total fetch time and fetch-time-related measures.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, that's fair. In that case, perhaps we should do something similar for the join time. Maybe we can have one field which tracks periodic join time and is reset after each reporting interval, and another field which tracks the total join time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added periodicJoinTimeInMs to track join time for a single interval.

@huxihx huxihx closed this Aug 23, 2017
@huxihx huxihx reopened this Sep 6, 2017
@huxihx
Copy link
Contributor Author

huxihx commented Sep 6, 2017

retest it please.

@huxihx
Copy link
Contributor Author

huxihx commented Sep 6, 2017

@hachikuji please review it again. Thanks

@hachikuji
Copy link
Contributor

retest this please

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.

Some more comments.

else
println("time, threadId, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec")
private[tools] def printHeader(showDetailedStats: Boolean, useOldConsumer: Boolean): Unit = {
val newFieldsInHeader = s"${if (!useOldConsumer) ", total.rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec" else ""}"
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 more straightforward to pull the if out of the string, eg:

if (!useOldConsumer) ", rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec" else ""

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed

println("start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec" + newFieldsInHeader)
} else {
println("time, threadId, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec" +
s"${if (useOldConsumer) "" else ", rebalance.time.ms" + newFieldsInHeader}")
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this redundant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean all these lines are redundant? Isn't it printing the header based on whether using old or new consumer and whether printing in detailed?

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant that the check for useOldConsumer is redundant give how we built newFieldsInHeader.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Checking useOldConsumer here is because new consumer should show the rebalance time for each interval as you suggest. However, the old consumer does not get this field displayed. Does it make sense?

def onPartitionsAssigned(partitions: util.Collection[TopicPartition]) {
isAssigned.set(true)
joinTime.addAndGet(System.currentTimeMillis - joinStart)
joinTimeMsInSingleRound = System.currentTimeMillis - joinStart
Copy link
Contributor

Choose a reason for hiding this comment

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

There could be multiple joins within each reporting period, so this should be a +=, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, you are right. Thanks.

joinStart = System.currentTimeMillis
}})
val joinStart = System.currentTimeMillis()
val joinStartForFirstTime = System.currentTimeMillis()
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we are now reporting the join time separately, I don't think we need the loop below anymore. It was initially intended to discount the rebalance overhead, but now we account for that transparently.

1000.0 * (mbRead / elapsedMs), messagesRead, ((messagesRead - lastMessagesRead) / elapsedMs) * 1000.0))
print("%s, %d, %.4f, %.4f, %d, %.4f".format(dateFormat.format(endMs), id, totalMBRead,
1000.0 * (mbRead / elapsedMs), messagesRead, ((messagesRead - lastMessagesRead) / elapsedMs) * 1000.0))
joinTimeOpt match {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should just move this block to a separate function so that we don't need all of the Option parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I am not sure if I fully understand this comment. Do you mean create a new function to handle all the printing things whereas printProgressMessage is that type of function?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it's a minor issue, but it's kind of annoying that we have three optional parameters which are all expected in the case of the new consumer. I think a cleaner approach is to use a separate method. Something approximately like this:

def printBasicProgress ...
def printExtraProgress ...

def printNewConsumerProgress {
  printBasicProgress()
  printExtraProgress()
  println()
}

def printOldConsumerProgress() {
  printBasicProgress()
  println()
}

Then we shouldn't need the optional parameters.

if (config.showDetailedStats)
printProgressMessage(0, bytesRead, lastBytesRead, messagesRead, lastMessagesRead, lastReportTime, currentTimeMillis, config.dateFormat)
printProgressMessage(0, bytesRead, lastBytesRead, messagesRead, lastMessagesRead,
lastReportTime, currentTimeMillis, config.dateFormat, Some(testStartTime), Some(joinTime.get), Some(joinTimeMsInSingleRound))
Copy link
Contributor

Choose a reason for hiding this comment

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

Is testStartTime correct? Shouldn't this be the beginning of the interval?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

testStartTime means the exact time where the entire consumer perf tool begins. Beginning of the interval for each round is 6th parameter of printProgressMessage. Does it make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

What I am not understanding is why we use the test start time when the other periodic statistics are computed based on the the interval start time. Shouldn't we be consistent?

@huxihx
Copy link
Contributor Author

huxihx commented Sep 15, 2017

@hachikuji Could you address my replied comments to see if they make any senses? Thanks.

case Some(joinTime) =>
val fetchTimeMs = endMs - beginTime.getOrElse(startMs) - joinTime
println(", %d, %d, %d, %.4f, %.4f".format(
periodicJoinTimeInMs.getOrElse(0L), joinTime, fetchTimeMs, (bytesRead * 1.0 / (1024 * 1024) / (fetchTimeMs / 1000.0)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we have two join times here? We only have one join time in the header, right? The periodic time should be enough I think.

1. refactoring printing to common functions
2. removed redundant codes
@huxihx
Copy link
Contributor Author

huxihx commented Sep 18, 2017

@hachikuji Thanks for the comments. Please review again.

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.

LGTM. Merging with a few fixes

@asfgit asfgit closed this in 239dad1 Sep 20, 2017
@hachikuji
Copy link
Contributor

@huxihx In the future, the review will go much faster if you are a bit more thorough with your testing. In this case, there were still some problems which would have been obvious had you executed the performance tool yourself manually.

  1. There was no newline printed after the normal (non-detailed) output.
  2. The detailed output was still computed inconsistently. If the join time for the interval was 0, then the fetch mb/sec (for example) should have exactly matched the total mb/sec. Same for messages/sec.

I fixed these problems during merging.

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