KAFKA-19011: Improve EndToEndLatency Tool with argument parser and message key/header support#20301
Conversation
…ssage key/header support
|
The updated usage of the tool with argument parser: It's compatible with the legacy version: |
Yunyung
left a comment
There was a problem hiding this comment.
Thanks for the PR. Partial review, some comments left. Also, could you add the KIP to the title or description?
|
|
||
| // validate 'producer-acks' | ||
| String acksValue = options.valueOf(acksOpt); | ||
| if (!List.of("1", "all").contains(acksValue)) { |
There was a problem hiding this comment.
The legacy version only had these two options, so I keep it the same. Since -1 has the same effect as all, I think one is enough?
| } | ||
|
|
||
| // Visible for testing | ||
| static String[] convertLegacyArgsIfNeeded(String[] args) throws Exception { |
There was a problem hiding this comment.
Should we add Deprecated tag?
There was a problem hiding this comment.
Thanks for pointing that out! Added it.
|
@Rancho-7 could you please run e2e on you local? |
|
@chia7712 I ran the tests with: e2e result: |
|
|
||
| // validate 'producer-acks' | ||
| String acksValue = options.valueOf(acksOpt); | ||
| if (!List.of("1", "all").contains(acksValue)) { |
| // optional | ||
| Optional<String> propertiesFile = opts.options.has(opts.commandConfigOpt) ? | ||
| Optional.of(opts.options.valueOf(opts.commandConfigOpt)) : Optional.empty(); | ||
| int recordKeySize = 0; |
There was a problem hiding this comment.
Why not add a default value to recordKeyOpt instead?
There was a problem hiding this comment.
You're right, using a default value would be much cleaner. Updated it.
|
|
||
| if (sentRecordKey != null) { | ||
| if (record.key() == null) { | ||
| throw new RuntimeException("Expected message key but received null"); |
There was a problem hiding this comment.
Should we commit the offsets too?
|
|
||
| for (int i = 0; i < numHeaders; i++) { | ||
| String headerKey = new String(randomBytesOfLen(random, keySize), StandardCharsets.UTF_8); | ||
| byte[] headerValue = randomBytesOfLen(random, valueSize); |
There was a problem hiding this comment.
Perhaps we should treat -1 as null for header value, since null is legal.
There was a problem hiding this comment.
Good point. Done.
| return args; | ||
| } | ||
|
|
||
| boolean hasNamedArgs = Arrays.stream(args).anyMatch(arg -> arg.startsWith("--")); |
There was a problem hiding this comment.
- is legal character in topic names, so it could cause an issue if users create a topic like topic--aaa. Perhaps we should check the required ops instead?
There was a problem hiding this comment.
Absolutely right! This would be a much safer approach. Thanks for catching this!
| newArgs.add(legacyArgs[4]); | ||
|
|
||
| // properties_file -> --command-config | ||
| if (legacyArgs.length == 6 && !legacyArgs[5].trim().isEmpty()) { |
There was a problem hiding this comment.
Excuse me, why to add !legacyArgs[5].trim().isEmpty() condition?
There was a problem hiding this comment.
Removed it, thanks!
| .withOptionalArg() | ||
| .describedAs("bytes") | ||
| .ofType(Integer.class) | ||
| .defaultsTo(0); |
There was a problem hiding this comment.
This is not discussed in the KIP. By default, the number of records is one, so should we create a non-empty header by default?
There was a problem hiding this comment.
Yes, that does feel a bit odd. Since the header is optional, maybe we should set the default num-headers to 0, and leave record-header-key-size and record-header-size empty?
| .withOptionalArg() | ||
| .describedAs("count") | ||
| .ofType(Integer.class) | ||
| .defaultsTo(1); |
There was a problem hiding this comment.
Could you please alos add those default values to the KIP?
There was a problem hiding this comment.
The KIP mentions that the default value for num-headers is set to 1, but it doesn't specify the default value for the other arguments. I will add that information to the KIP. Thanks!
| for (int i = 0; i < numHeaders; i++) { | ||
| String headerKey = new String(randomBytesOfLen(random, keySize), StandardCharsets.UTF_8); | ||
| byte[] headerValue = valueSize == -1 ? null : randomBytesOfLen(random, valueSize); | ||
| headers.add(new RecordHeader(headerKey, headerValue)); |
There was a problem hiding this comment.
RecordHeader is internal class. Perhaps we could add a record class instead
| List<Header> headers = new ArrayList<>(); | ||
|
|
||
| for (int i = 0; i < numHeaders; i++) { | ||
| String headerKey = new String(randomBytesOfLen(random, keySize), StandardCharsets.UTF_8); |
There was a problem hiding this comment.
Have you considered directly generating a random string?
There was a problem hiding this comment.
Not yet. The randomBytesOfLen function was used in the earlier version, and I found it could be reused, so I kept it.
| throw new IllegalArgumentException("Latency testing requires synchronous acknowledgement. Please use 1 or all"); | ||
| } | ||
| // optional | ||
| Optional<String> propertiesFile = opts.options.has(opts.commandConfigOpt) ? |
There was a problem hiding this comment.
Optional<String> propertiesFile = Optional.ofNullable(opts.options.valueOf(opts.commandConfigOpt));| if (options.has(recordHeaderKeySizeOpt) && options.valueOf(recordHeaderKeySizeOpt) < 0) { | ||
| CommandLineUtils.printUsageAndExit(parser, "Value for --record-header-key-size must be a non-negative integer."); | ||
| } | ||
| if (options.has(recordHeaderValueSizeOpt) && options.valueOf(recordHeaderValueSizeOpt) < -1) { |
There was a problem hiding this comment.
Is options.has(recordHeaderValueSizeOpt) necessary since recordHeaderValueSizeOpt has default value?
There was a problem hiding this comment.
Thanks for catching this! I have removed all these unnecessary checks.
…sage key/header support (apache#20301) jira: https://issues.apache.org/jira/browse/KAFKA-19011 kip: https://cwiki.apache.org/confluence/display/KAFKA/KIP-1172%3A+Improve+EndToEndLatency+tool This PR improves the usability and maintainability of the `kafka-e2e-latency.sh` tool: - Replaces fixed-index argument parsing with a proper argument parser (joptsimple) - Adds support for configuring: - -record-key-size: size of the message key - -num-headers: number of headers per message - -record-header-key-size: size of each header key - -record-header-size: size of each header value - Renames existing arguments to align with Kafka CLI conventions: - broker_list → bootstrap-server - num_messages → num-records - message_size_bytes → record-size - properties_file → command-config - Reviewers: Jhen-Yung Hsu <jhenyunghsu@gmail.com>, Ken Huang <s7133700@gmail.com>, Chia-Ping Tsai <chia7712@gmail.com>
jira: https://issues.apache.org/jira/browse/KAFKA-19011 kip:
https://cwiki.apache.org/confluence/display/KAFKA/KIP-1172%3A+Improve+EndToEndLatency+tool
This PR improves the usability and maintainability of the
kafka-e2e-latency.shtool:(joptsimple)
Reviewers: Jhen-Yung Hsu jhenyunghsu@gmail.com, Ken Huang
s7133700@gmail.com, Chia-Ping Tsai chia7712@gmail.com