This is an automated email from the ASF dual-hosted git repository.
sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/master by this push:
new c0fdfa5 ISSUE #468: Introduce JMH for micro benchmarking
c0fdfa5 is described below
commit c0fdfa5c1a05bd5cadb175928aa02a8e1c3f1e1f
Author: Sijie Guo <[email protected]>
AuthorDate: Mon Aug 28 02:09:45 2017 -0700
ISSUE #468: Introduce JMH for micro benchmarking
Descriptions of the changes in this PR:
- add a `test/jmh` module for micro-benchmarking
- add a protocol related test: serializing and deserializing requests
Author: Sijie Guo <[email protected]>
Reviewers: Jia Zhai <None>, Matteo Merli <[email protected]>
This patch had conflicts when merged, resolved by
Committer: Sijie Guo <[email protected]>
This closes #469 from sijie/add_jmh_benchmark, closes #468
---
.../bookkeeper/proto/BookieProtoEncoding.java | 18 +--
.../apache/bookkeeper/proto/BookieProtocol.java | 4 +-
.../main/resources/bookkeeper/findbugsExclude.xml | 4 +
pom.xml | 3 +-
tests/jmh/pom.xml | 100 ++++++++++++++++
.../apache/bookkeeper/tests/ProtocolBenchmark.java | 126 +++++++++++++++++++++
6 files changed, 243 insertions(+), 12 deletions(-)
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtoEncoding.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtoEncoding.java
index 8988cc9..0fece29 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtoEncoding.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtoEncoding.java
@@ -71,7 +71,7 @@ public class BookieProtoEncoding {
}
- static class RequestEnDeCoderPreV3 implements EnDecoder {
+ public static class RequestEnDeCoderPreV3 implements EnDecoder {
final ExtensionRegistry extensionRegistry;
//This empty master key is used when an empty password is provided
which is the hash of an empty string
@@ -84,7 +84,7 @@ public class BookieProtoEncoding {
}
}
- RequestEnDeCoderPreV3(ExtensionRegistry extensionRegistry) {
+ public RequestEnDeCoderPreV3(ExtensionRegistry extensionRegistry) {
this.extensionRegistry = extensionRegistry;
}
@@ -205,10 +205,10 @@ public class BookieProtoEncoding {
}
}
- static class ResponseEnDeCoderPreV3 implements EnDecoder {
+ public static class ResponseEnDeCoderPreV3 implements EnDecoder {
final ExtensionRegistry extensionRegistry;
- ResponseEnDeCoderPreV3(ExtensionRegistry extensionRegistry) {
+ public ResponseEnDeCoderPreV3(ExtensionRegistry extensionRegistry) {
this.extensionRegistry = extensionRegistry;
}
@@ -288,10 +288,10 @@ public class BookieProtoEncoding {
}
}
- static class RequestEnDecoderV3 implements EnDecoder {
+ public static class RequestEnDecoderV3 implements EnDecoder {
final ExtensionRegistry extensionRegistry;
- RequestEnDecoderV3(ExtensionRegistry extensionRegistry) {
+ public RequestEnDecoderV3(ExtensionRegistry extensionRegistry) {
this.extensionRegistry = extensionRegistry;
}
@@ -308,10 +308,10 @@ public class BookieProtoEncoding {
}
- static class ResponseEnDecoderV3 implements EnDecoder {
+ public static class ResponseEnDecoderV3 implements EnDecoder {
final ExtensionRegistry extensionRegistry;
- ResponseEnDecoderV3(ExtensionRegistry extensionRegistry) {
+ public ResponseEnDecoderV3(ExtensionRegistry extensionRegistry) {
this.extensionRegistry = extensionRegistry;
}
@@ -351,7 +351,7 @@ public class BookieProtoEncoding {
final EnDecoder REQ_PREV3;
final EnDecoder REQ_V3;
- RequestEncoder(ExtensionRegistry extensionRegistry) {
+ public RequestEncoder(ExtensionRegistry extensionRegistry) {
REQ_PREV3 = new RequestEnDeCoderPreV3(extensionRegistry);
REQ_V3 = new RequestEnDecoderV3(extensionRegistry);
}
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
index 4df4044..99c33fb 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
@@ -238,8 +238,8 @@ public interface BookieProtocol {
static class AddRequest extends Request {
final ByteBuf data;
- AddRequest(byte protocolVersion, long ledgerId, long entryId,
- short flags, byte[] masterKey, ByteBuf data) {
+ public AddRequest(byte protocolVersion, long ledgerId, long entryId,
+ short flags, byte[] masterKey, ByteBuf data) {
super(protocolVersion, ADDENTRY, ledgerId, entryId, flags,
masterKey);
this.data = data.retain();
}
diff --git a/buildtools/src/main/resources/bookkeeper/findbugsExclude.xml
b/buildtools/src/main/resources/bookkeeper/findbugsExclude.xml
index e8dad26..efee56a 100644
--- a/buildtools/src/main/resources/bookkeeper/findbugsExclude.xml
+++ b/buildtools/src/main/resources/bookkeeper/findbugsExclude.xml
@@ -25,6 +25,10 @@
<Class name="~org\.apache\.bookkeeper\.proto\.BookkeeperProtocol.*" />
</Match>
<Match>
+ <!-- generated code, we can't be held responsible for findbugs in it //-->
+ <Class name="~org\.apache\.bookkeeper\.tests\.generated.*" />
+ </Match>
+ <Match>
<!-- it is safe to store external bytes reference here. since we are using
bytes from a slab. //-->
<Class name="org.apache.bookkeeper.bookie.EntryKeyValue" />
diff --git a/pom.xml b/pom.xml
index 334de10..8b79a51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,7 @@
<!-- dependencies -->
<guava.version>20.0</guava.version>
<hamcrest.version>1.3</hamcrest.version>
+ <jmh.version>1.19</jmh.version>
<junit.version>4.12</junit.version>
<protobuf.version>3.4.0</protobuf.version>
<netty.version>4.1.12.Final</netty.version>
@@ -358,4 +359,4 @@
</build>
</profile>
</profiles>
-</project>
\ No newline at end of file
+</project>
diff --git a/tests/jmh/pom.xml b/tests/jmh/pom.xml
new file mode 100644
index 0000000..f7df3d2
--- /dev/null
+++ b/tests/jmh/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.bookkeeper.tests</groupId>
+ <artifactId>tests-parent</artifactId>
+ <version>4.6.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>jmh-test</artifactId>
+ <name>Apache BookKeeper :: Tests :: JMH Benchmark</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.bookkeeper</groupId>
+ <artifactId>bookkeeper-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <!--
+ Name of the benchmark Uber-JAR to generate.
+ -->
+ <uberjar.name>jmh-benchmarks</uberjar.name>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>${maven-shade-plugin.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <finalName>${uberjar.name}</finalName>
+ <transformers>
+ <transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.openjdk.jmh.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <!--
+ Shading signed JARs will fail without this.
+
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
+ -->
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git
a/tests/jmh/src/main/java/org/apache/bookkeeper/tests/ProtocolBenchmark.java
b/tests/jmh/src/main/java/org/apache/bookkeeper/tests/ProtocolBenchmark.java
new file mode 100644
index 0000000..c87549f
--- /dev/null
+++ b/tests/jmh/src/main/java/org/apache/bookkeeper/tests/ProtocolBenchmark.java
@@ -0,0 +1,126 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.bookkeeper.tests;
+
+import static com.google.common.base.Charsets.UTF_8;
+
+import com.google.protobuf.ByteString;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.buffer.Unpooled;
+import io.netty.util.ReferenceCountUtil;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import org.apache.bookkeeper.proto.BookieProtoEncoding.EnDecoder;
+import org.apache.bookkeeper.proto.BookieProtoEncoding.RequestEnDeCoderPreV3;
+import org.apache.bookkeeper.proto.BookieProtoEncoding.RequestEnDecoderV3;
+import org.apache.bookkeeper.proto.BookieProtocol;
+import org.apache.bookkeeper.proto.BookkeeperProtocol.AddRequest;
+import org.apache.bookkeeper.proto.BookkeeperProtocol.BKPacketHeader;
+import org.apache.bookkeeper.proto.BookkeeperProtocol.OperationType;
+import org.apache.bookkeeper.proto.BookkeeperProtocol.ProtocolVersion;
+import org.apache.bookkeeper.proto.BookkeeperProtocol.Request;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+/**
+ * Benchmarking serialization and deserilization.
+ */
+@BenchmarkMode({ Mode.Throughput })
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class ProtocolBenchmark {
+
+ @Param({ "10", "100", "1000", "10000" })
+ int size;
+
+ byte[] masterKey;
+ ByteBuf entry;
+ long ledgerId;
+ long entryId;
+ short flags;
+ EnDecoder reqEnDeV2;
+ EnDecoder reqEnDeV3;
+
+ @Setup
+ public void prepare() {
+ this.masterKey = "test-benchmark-key".getBytes(UTF_8);
+ Random r = new Random(System.currentTimeMillis());
+ byte[] data = new byte[this.size];
+ r.nextBytes(data);
+ this.entry = Unpooled.wrappedBuffer(data);
+ this.ledgerId = r.nextLong();
+ this.entryId = r.nextLong();
+ this.flags = 1;
+
+ // prepare the encoder
+ this.reqEnDeV2 = new RequestEnDeCoderPreV3(null);
+ this.reqEnDeV3 = new RequestEnDecoderV3(null);
+ }
+
+
+ @Benchmark
+ public void testAddEntryV2() throws Exception {
+ BookieProtocol.AddRequest req = new BookieProtocol.AddRequest(
+ BookieProtocol.CURRENT_PROTOCOL_VERSION,
+ ledgerId,
+ entryId,
+ flags,
+ masterKey,
+ entry.slice());
+ Object res = this.reqEnDeV2.encode(req, ByteBufAllocator.DEFAULT);
+ ReferenceCountUtil.release(res);
+ }
+
+ @Benchmark
+ public void testAddEntryV3() throws Exception {
+ // Build the request and calculate the total size to be included in
the packet.
+ BKPacketHeader.Builder headerBuilder = BKPacketHeader.newBuilder()
+ .setVersion(ProtocolVersion.VERSION_THREE)
+ .setOperation(OperationType.ADD_ENTRY)
+ .setTxnId(0L);
+
+ ByteBuf toSend = entry.slice();
+ byte[] toSendArray = new byte[toSend.readableBytes()];
+ toSend.getBytes(toSend.readerIndex(), toSendArray);
+ AddRequest.Builder addBuilder = AddRequest.newBuilder()
+ .setLedgerId(ledgerId)
+ .setEntryId(entryId)
+ .setMasterKey(ByteString.copyFrom(masterKey))
+ .setBody(ByteString.copyFrom(toSendArray))
+ .setFlag(AddRequest.Flag.RECOVERY_ADD);
+
+ Request request = Request.newBuilder()
+ .setHeader(headerBuilder)
+ .setAddRequest(addBuilder)
+ .build();
+
+ Object res = this.reqEnDeV3.encode(request, ByteBufAllocator.DEFAULT);
+ ReferenceCountUtil.release(res);
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].