This patch rewrites `ProduceRequest` and `ProduceResponse` using the generated protocols. We have also added several new benchmarks to verify no regression in performance. A summary of results is included below:
### Benchmark
1. loop **30** times
1. calculate average
#### kafkatest.benchmarks.core.benchmark_test.Benchmark.test_producer_throughput
> @cluster(num_nodes=5)
> @parametrize(acks=-1, topic=TOPIC_REP_THREE)
- +0.3144915325 %
- 28.08766667 -> 28.1715625 (mb_per_sec)
> @cluster(num_nodes=5)
> @matrix(acks=[1], topic=[TOPIC_REP_THREE], message_size=[100000],compression_type=["none"], security_protocol=['PLAINTEXT'])
- +4.220730323 %
- 157.145 -> 163.7776667 (mb_per_sec)
> @cluster(num_nodes=7)
> @parametrize(acks=1, topic=TOPIC_REP_THREE, num_producers=3)
- +5.996241145%
- 57.64166667 -> 61.098 (mb_per_sec)
> @cluster(num_nodes=5)
> @parametrize(acks=1, topic=TOPIC_REP_THREE)
- +0.3979572536%
- 44.05833333 -> 44.23366667 (mb_per_sec)
> @cluster(num_nodes=5)
> @parametrize(acks=1, topic= TOPIC_REP_ONE)
- +2.228235226%
- 69.23266667 -> 70.77533333 (mb_per_sec)
### JMH results
In short, most ops performance are regression since we have to convert data to protocol data. The cost is inevitable (like other request/response) before we use protocol data directly.
### JMH for ProduceRequest
1. construction regression:
- 281.474 -> 454.935 ns/op
- 296.000 -> 1888.000 B/op
1. toErrorResponse regression:
- 41.942 -> 107.528 ns/op
- 1216.000 -> 1616.000 B/op
1. toStruct improvement:
- 255.185 -> 90.728 ns/op
- 864.000 -> 304.000 B/op
**BEFORE**
```
Benchmark Mode Cnt Score Error Units
ProducerRequestBenchmark.constructorErrorResponse avgt 15 41.942 ± 0.036 ns/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.alloc.rate avgt 15 6409.263 ± 5.478 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.alloc.rate.norm avgt 15 296.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Eden_Space avgt 15 6416.420 ± 76.071 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Eden_Space.norm avgt 15 296.331 ± 3.539 B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Old_Gen avgt 15 0.002 ± 0.002 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Old_Gen.norm avgt 15 ≈ 10⁻⁴ B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.count avgt 15 698.000 counts
ProducerRequestBenchmark.constructorErrorResponse:·gc.time avgt 15 378.000 ms
ProducerRequestBenchmark.constructorProduceRequest avgt 15 281.474 ± 3.286 ns/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.alloc.rate avgt 15 3923.868 ± 46.303 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.alloc.rate.norm avgt 15 1216.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Eden_Space avgt 15 3923.375 ± 59.568 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Eden_Space.norm avgt 15 1215.844 ± 11.184 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Old_Gen avgt 15 0.004 ± 0.001 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Old_Gen.norm avgt 15 0.001 ± 0.001 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.count avgt 15 515.000 counts
ProducerRequestBenchmark.constructorProduceRequest:·gc.time avgt 15 279.000 ms
ProducerRequestBenchmark.constructorStruct avgt 15 255.185 ± 0.069 ns/op
ProducerRequestBenchmark.constructorStruct:·gc.alloc.rate avgt 15 3074.889 ± 0.823 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.alloc.rate.norm avgt 15 864.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Eden_Space avgt 15 3077.737 ± 31.537 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Eden_Space.norm avgt 15 864.800 ± 8.823 B/op
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Old_Gen avgt 15 0.003 ± 0.001 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Old_Gen.norm avgt 15 0.001 ± 0.001 B/op
ProducerRequestBenchmark.constructorStruct:·gc.count avgt 15 404.000 counts
ProducerRequestBenchmark.constructorStruct:·gc.time avgt 15 214.000 ms
```
**AFTER**
```
Benchmark Mode Cnt Score Error Units
ProducerRequestBenchmark.constructorErrorResponse avgt 15 107.528 ± 0.270 ns/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.alloc.rate avgt 15 4864.899 ± 12.132 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.alloc.rate.norm avgt 15 576.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Eden_Space avgt 15 4868.023 ± 61.943 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Eden_Space.norm avgt 15 576.371 ± 7.331 B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Old_Gen avgt 15 0.005 ± 0.001 MB/sec
ProducerRequestBenchmark.constructorErrorResponse:·gc.churn.G1_Old_Gen.norm avgt 15 0.001 ± 0.001 B/op
ProducerRequestBenchmark.constructorErrorResponse:·gc.count avgt 15 639.000 counts
ProducerRequestBenchmark.constructorErrorResponse:·gc.time avgt 15 339.000 ms
ProducerRequestBenchmark.constructorProduceRequest avgt 15 454.935 ± 0.332 ns/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.alloc.rate avgt 15 3769.014 ± 2.767 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.alloc.rate.norm avgt 15 1888.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Eden_Space avgt 15 3763.407 ± 31.530 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Eden_Space.norm avgt 15 1885.190 ± 15.594 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Old_Gen avgt 15 0.004 ± 0.001 MB/sec
ProducerRequestBenchmark.constructorProduceRequest:·gc.churn.G1_Old_Gen.norm avgt 15 0.002 ± 0.001 B/op
ProducerRequestBenchmark.constructorProduceRequest:·gc.count avgt 15 494.000 counts
ProducerRequestBenchmark.constructorProduceRequest:·gc.time avgt 15 264.000 ms
ProducerRequestBenchmark.constructorStruct avgt 15 90.728 ± 0.695 ns/op
ProducerRequestBenchmark.constructorStruct:·gc.alloc.rate avgt 15 3043.140 ± 23.246 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.alloc.rate.norm avgt 15 304.000 ± 0.001 B/op
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Eden_Space avgt 15 3047.251 ± 59.638 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Eden_Space.norm avgt 15 304.404 ± 5.034 B/op
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Old_Gen avgt 15 0.003 ± 0.001 MB/sec
ProducerRequestBenchmark.constructorStruct:·gc.churn.G1_Old_Gen.norm avgt 15 ≈ 10⁻⁴ B/op
ProducerRequestBenchmark.constructorStruct:·gc.count avgt 15 400.000 counts
ProducerRequestBenchmark.constructorStruct:·gc.time avgt 15 205.000 ms
```
### JMH for ProduceResponse
1. construction regression:
- 3.293 -> 303.226 ns/op
- 24.000 -> 1848.000 B/op
1. toStruct improvement:
- 825.889 -> 311.725 ns/op
- 2208.000 -> 896.000 B/op
**BEFORE**
```
Benchmark Mode Cnt Score Error Units
ProducerResponseBenchmark.constructorProduceResponse avgt 15 3.293 ± 0.004 ns/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.alloc.rate avgt 15 6619.731 ± 9.075 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.alloc.rate.norm avgt 15 24.000 ± 0.001 B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Eden_Space avgt 15 6618.648 ± 0.153 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Eden_Space.norm avgt 15 23.996 ± 0.033 B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Old_Gen avgt 15 0.003 ± 0.002 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Old_Gen.norm avgt 15 ≈ 10⁻⁵ B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.count avgt 15 720.000 counts
ProducerResponseBenchmark.constructorProduceResponse:·gc.time avgt 15 383.000 ms
ProducerResponseBenchmark.constructorStruct avgt 15 825.889 ± 0.638 ns/op
ProducerResponseBenchmark.constructorStruct:·gc.alloc.rate avgt 15 2428.000 ± 1.899 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.alloc.rate.norm avgt 15 2208.000 ± 0.001 B/op
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Eden_Space avgt 15 2430.196 ± 55.894 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Eden_Space.norm avgt 15 2210.001 ± 51.009 B/op
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Old_Gen avgt 15 0.003 ± 0.001 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Old_Gen.norm avgt 15 0.002 ± 0.001 B/op
ProducerResponseBenchmark.constructorStruct:·gc.count avgt 15 319.000 counts
ProducerResponseBenchmark.constructorStruct:·gc.time avgt 15 166.000 ms
```
**AFTER**
```
Benchmark Mode Cnt Score Error Units
ProducerResponseBenchmark.constructorProduceResponse avgt 15 303.226 ± 0.517 ns/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.alloc.rate avgt 15 5534.940 ± 9.439 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.alloc.rate.norm avgt 15 1848.000 ± 0.001 B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Eden_Space avgt 15 5534.046 ± 51.849 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Eden_Space.norm avgt 15 1847.710 ± 18.105 B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Old_Gen avgt 15 0.007 ± 0.001 MB/sec
ProducerResponseBenchmark.constructorProduceResponse:·gc.churn.G1_Old_Gen.norm avgt 15 0.002 ± 0.001 B/op
ProducerResponseBenchmark.constructorProduceResponse:·gc.count avgt 15 602.000 counts
ProducerResponseBenchmark.constructorProduceResponse:·gc.time avgt 15 318.000 ms
ProducerResponseBenchmark.constructorStruct avgt 15 311.725 ± 3.132 ns/op
ProducerResponseBenchmark.constructorStruct:·gc.alloc.rate avgt 15 2610.602 ± 25.964 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.alloc.rate.norm avgt 15 896.000 ± 0.001 B/op
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Eden_Space avgt 15 2613.021 ± 42.965 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Eden_Space.norm avgt 15 896.824 ± 11.331 B/op
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Old_Gen avgt 15 0.003 ± 0.001 MB/sec
ProducerResponseBenchmark.constructorStruct:·gc.churn.G1_Old_Gen.norm avgt 15 0.001 ± 0.001 B/op
ProducerResponseBenchmark.constructorStruct:·gc.count avgt 15 343.000 counts
ProducerResponseBenchmark.constructorStruct:·gc.time avgt 15 194.000 ms
```
Reviewers: David Jacot <djacot@confluent.io>, Jason Gustafson <jason@confluent.io>
|
||
|---|---|---|
| bin | ||
| checkstyle | ||
| clients | ||
| config | ||
| connect | ||
| core | ||
| docs | ||
| examples | ||
| generator/src | ||
| gradle | ||
| jmh-benchmarks | ||
| log4j-appender/src | ||
| raft | ||
| streams | ||
| tests | ||
| tools/src | ||
| vagrant | ||
| .asf.yaml | ||
| .gitignore | ||
| .travis.yml | ||
| CONTRIBUTING.md | ||
| HEADER | ||
| Jenkinsfile | ||
| LICENSE | ||
| NOTICE | ||
| PULL_REQUEST_TEMPLATE.md | ||
| README.md | ||
| TROGDOR.md | ||
| Vagrantfile | ||
| build.gradle | ||
| doap_Kafka.rdf | ||
| gradle.properties | ||
| gradlew | ||
| gradlewAll | ||
| jenkins.sh | ||
| kafka-merge-pr.py | ||
| release.py | ||
| release_notes.py | ||
| settings.gradle | ||
| wrapper.gradle | ||
README.md
Apache Kafka
See our web site for details on the project.
You need to have Java installed.
We build and test Apache Kafka with Java 8, 11 and 15. We set the release parameter in javac and scalac
to 8 to ensure the generated binaries are compatible with Java 8 or higher (independently of the Java version
used for compilation).
Scala 2.13 is used by default, see below for how to use a different Scala version or all of the supported Scala versions.
Build a jar and run it
./gradlew jar
Follow instructions in https://kafka.apache.org/quickstart
Build source jar
./gradlew srcJar
Build aggregated javadoc
./gradlew aggregatedJavadoc
Build javadoc and scaladoc
./gradlew javadoc
./gradlew javadocJar # builds a javadoc jar for each module
./gradlew scaladoc
./gradlew scaladocJar # builds a scaladoc jar for each module
./gradlew docsJar # builds both (if applicable) javadoc and scaladoc jars for each module
Run unit/integration tests
./gradlew test # runs both unit and integration tests
./gradlew unitTest
./gradlew integrationTest
Force re-running tests without code change
./gradlew cleanTest test
./gradlew cleanTest unitTest
./gradlew cleanTest integrationTest
Running a particular unit/integration test
./gradlew clients:test --tests RequestResponseTest
Running a particular test method within a unit/integration test
./gradlew core:test --tests kafka.api.ProducerFailureHandlingTest.testCannotSendToInternalTopic
./gradlew clients:test --tests org.apache.kafka.clients.MetadataTest.testMetadataUpdateWaitTime
Running a particular unit/integration test with log4j output
Change the log4j setting in either clients/src/test/resources/log4j.properties or core/src/test/resources/log4j.properties
./gradlew clients:test --tests RequestResponseTest
Specifying test retries
By default, each failed test is retried once up to a maximum of five retries per test run. Tests are retried at the end of the test task. Adjust these parameters in the following way:
./gradlew test -PmaxTestRetries=1 -PmaxTestRetryFailures=5
See Test Retry Gradle Plugin for more details.
Generating test coverage reports
Generate coverage reports for the whole project:
./gradlew reportCoverage -PenableTestCoverage=true
Generate coverage for a single module, i.e.:
./gradlew clients:reportCoverage -PenableTestCoverage=true
Building a binary release gzipped tar ball
./gradlew clean releaseTarGz
The above command will fail if you haven't set up the signing key. To bypass signing the artifact, you can run:
./gradlew clean releaseTarGz -x signArchives
The release file can be found inside ./core/build/distributions/.
Building auto generated messages
Sometimes it is only necessary to rebuild the RPC auto-generated message data when switching between branches, as they could fail due to code changes. You can just run:
./gradlew processMessages processTestMessages
Cleaning the build
./gradlew clean
Running a task with one of the Scala versions available (2.12.x or 2.13.x)
Note that if building the jars with a version other than 2.13.x, you need to set the SCALA_VERSION variable or change it in bin/kafka-run-class.sh to run the quick start.
You can pass either the major version (eg 2.12) or the full version (eg 2.12.7):
./gradlew -PscalaVersion=2.12 jar
./gradlew -PscalaVersion=2.12 test
./gradlew -PscalaVersion=2.12 releaseTarGz
Running a task with all the scala versions enabled by default
Invoke the gradlewAll script followed by the task(s):
./gradlewAll test
./gradlewAll jar
./gradlewAll releaseTarGz
Running a task for a specific project
This is for core, examples and clients
./gradlew core:jar
./gradlew core:test
Streams has multiple sub-projects, but you can run all the tests:
./gradlew :streams:testAll
Listing all gradle tasks
./gradlew tasks
Building IDE project
Note that this is not strictly necessary (IntelliJ IDEA has good built-in support for Gradle projects, for example).
./gradlew eclipse
./gradlew idea
The eclipse task has been configured to use ${project_dir}/build_eclipse as Eclipse's build directory. Eclipse's default
build directory (${project_dir}/bin) clashes with Kafka's scripts directory and we don't use Gradle's build directory
to avoid known issues with this configuration.
Publishing the jar for all version of Scala and for all projects to maven
./gradlewAll uploadArchives
Please note for this to work you should create/update ${GRADLE_USER_HOME}/gradle.properties (typically, ~/.gradle/gradle.properties) and assign the following variables
mavenUrl=
mavenUsername=
mavenPassword=
signing.keyId=
signing.password=
signing.secretKeyRingFile=
Publishing the streams quickstart archetype artifact to maven
For the Streams archetype project, one cannot use gradle to upload to maven; instead the mvn deploy command needs to be called at the quickstart folder:
cd streams/quickstart
mvn deploy
Please note for this to work you should create/update user maven settings (typically, ${USER_HOME}/.m2/settings.xml) to assign the following variables
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<servers>
...
<server>
<id>apache.snapshots.https</id>
<username>${maven_username}</username>
<password>${maven_password}</password>
</server>
<server>
<id>apache.releases.https</id>
<username>${maven_username}</username>
<password>${maven_password}</password>
</server>
...
</servers>
...
Installing the jars to the local Maven repository
./gradlewAll install
Building the test jar
./gradlew testJar
Determining how transitive dependencies are added
./gradlew core:dependencies --configuration runtime
Determining if any dependencies could be updated
./gradlew dependencyUpdates
Running code quality checks
There are two code quality analysis tools that we regularly run, spotbugs and checkstyle.
Checkstyle
Checkstyle enforces a consistent coding style in Kafka. You can run checkstyle using:
./gradlew checkstyleMain checkstyleTest
The checkstyle warnings will be found in reports/checkstyle/reports/main.html and reports/checkstyle/reports/test.html files in the
subproject build directories. They are also printed to the console. The build will fail if Checkstyle fails.
Spotbugs
Spotbugs uses static analysis to look for bugs in the code. You can run spotbugs using:
./gradlew spotbugsMain spotbugsTest -x test
The spotbugs warnings will be found in reports/spotbugs/main.html and reports/spotbugs/test.html files in the subproject build
directories. Use -PxmlSpotBugsReport=true to generate an XML report instead of an HTML one.
Common build options
The following options should be set with a -P switch, for example ./gradlew -PmaxParallelForks=1 test.
commitId: sets the build commit ID as .git/HEAD might not be correct if there are local commits added for build purposes.mavenUrl: sets the URL of the maven deployment repository (file://path/to/repocan be used to point to a local repository).maxParallelForks: limits the maximum number of processes for each task.ignoreFailures: ignore test failures from junitshowStandardStreams: shows standard out and standard error of the test JVM(s) on the console.skipSigning: skips signing of artifacts.testLoggingEvents: unit test events to be logged, separated by comma. For example./gradlew -PtestLoggingEvents=started,passed,skipped,failed test.xmlSpotBugsReport: enable XML reports for spotBugs. This also disables HTML reports as only one can be enabled at a time.maxTestRetries: the maximum number of retries for a failing test case.maxTestRetryFailures: maximum number of test failures before retrying is disabled for subsequent tests.enableTestCoverage: enables test coverage plugins and tasks, including bytecode enhancement of classes required to track said coverage. Note that this introduces some overhead when running tests and hence why it's disabled by default (the overhead varies, but 15-20% is a reasonable estimate).
Dependency Analysis
The gradle dependency debugging documentation mentions using the dependencies or dependencyInsight tasks to debug dependencies for the root project or individual subprojects.
Alternatively, use the allDeps or allDepInsight tasks for recursively iterating through all subprojects:
./gradlew allDeps
./gradlew allDepInsight --configuration runtime --dependency com.fasterxml.jackson.core:jackson-databind
These take the same arguments as the builtin variants.
Running system tests
See tests/README.md.
Running in Vagrant
See vagrant/README.md.
Contribution
Apache Kafka is interested in building the community; we would welcome any thoughts or patches. You can reach us on the Apache mailing lists.
To contribute follow the instructions here: