Bläddra i källkod

Upgrade to Vert.x 4.3.5 + cached queries benchmark (#7721)

* Upgrade to Vert.x 4.3.5

* Implement Caching benchmark with Caffeine cache
Julien Viet 2 år sedan
förälder
incheckning
b87408b3aa

+ 9 - 1
frameworks/Java/vertx/README.md

@@ -26,10 +26,14 @@ This is the Vert.x portion of a [benchmarking test suite](../) comparing a varie
 
 * [Template rendering test source](src/main/java/vertx/App.java)
 
+### Caching Test
+
+* [Caching test source](src/main/java/vertx/App.java)
+
 ## Versions
 
 * [Java 11](https://jdk.java.net)
-* [vertx 4.1.3](http://vertx.io/)
+* [vertx 4.3.5](http://vertx.io/)
 
 ## Test URLs
 
@@ -56,3 +60,7 @@ This is the Vert.x portion of a [benchmarking test suite](../) comparing a varie
 ### Template rendering Test
 
     http://localhost:8080/fortunes
+
+### Cached Query Test
+
+    http://localhost:8080/cached-queries?count=10

+ 1 - 0
frameworks/Java/vertx/benchmark_config.json

@@ -25,6 +25,7 @@
       "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
       "update_url": "/updates?queries=",
+      "cached_query_url": "/cached-queries?count=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 1 - 0
frameworks/Java/vertx/config.toml

@@ -19,6 +19,7 @@ urls.db = "/db"
 urls.query = "/queries?queries="
 urls.update = "/updates?queries="
 urls.fortune = "/fortunes"
+urls.cached_query = "/cached-queries?count="
 approach = "Realistic"
 classification = "Platform"
 database = "Postgres"

+ 8 - 3
frameworks/Java/vertx/pom.xml

@@ -10,9 +10,9 @@
 		<maven.compiler.target>11</maven.compiler.target>
 		<!-- the main class -->
 		<main.class>vertx.App</main.class>
-		<stack.version>4.1.4</stack.version>
-		<jackson.version>2.13.3</jackson.version>
-		<netty.version>4.1.67.Final</netty.version>
+		<stack.version>4.3.5</stack.version>
+		<jackson.version>2.4.0</jackson.version>
+		<netty.version>4.1.85.Final</netty.version>
 	</properties>
 
 	<dependencies>
@@ -48,6 +48,11 @@
 			<version>${netty.version}</version>
 			<classifier>linux-x86_64</classifier>
 		</dependency>
+		<dependency>
+			<groupId>com.github.ben-manes.caffeine</groupId>
+			<artifactId>caffeine</artifactId>
+			<version>3.1.1</version>
+		</dependency>
 		<dependency>
 			<groupId>com.fizzed</groupId>
 			<artifactId>rocker-compiler</artifactId>

+ 41 - 3
frameworks/Java/vertx/src/main/java/vertx/App.java

@@ -16,7 +16,6 @@ import io.vertx.core.json.JsonArray;
 import io.vertx.core.json.JsonObject;
 import io.vertx.core.logging.Logger;
 import io.vertx.core.logging.LoggerFactory;
-import io.vertx.sqlclient.PoolOptions;
 import io.vertx.sqlclient.PreparedQuery;
 import io.vertx.sqlclient.PreparedStatement;
 import io.vertx.sqlclient.Row;
@@ -24,10 +23,11 @@ import io.vertx.sqlclient.RowIterator;
 import io.vertx.sqlclient.RowSet;
 import io.vertx.sqlclient.Tuple;
 import io.vertx.sqlclient.impl.SqlClientInternal;
-import io.vertx.sqlclient.impl.command.CompositeCommand;
+import vertx.model.CachedWorld;
 import vertx.model.Fortune;
 import vertx.model.Message;
 import vertx.model.World;
+import vertx.model.WorldCache;
 import vertx.rocker.BufferRockerOutput;
 
 import java.io.ByteArrayOutputStream;
@@ -40,8 +40,10 @@ import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.Collectors;
 
 public class App extends AbstractVerticle implements Handler<HttpServerRequest> {
 
@@ -74,6 +76,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   private static final String PATH_QUERIES = "/queries";
   private static final String PATH_UPDATES = "/updates";
   private static final String PATH_FORTUNES = "/fortunes";
+  private static final String PATH_CACHING = "/cached-queries";
 
   private static final Handler<AsyncResult<Void>> NULL_HANDLER = null;
 
@@ -95,6 +98,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   private static final String UPDATE_WORLD = "UPDATE world SET randomnumber=$1 WHERE id=$2";
   private static final String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1";
   private static final String SELECT_FORTUNE = "SELECT id, message from FORTUNE";
+  private static final String SELECT_WORLDS = "SELECT id, randomnumber from WORLD";
 
   private HttpServer server;
 
@@ -109,6 +113,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   private PreparedQuery<RowSet<Row>> SELECT_WORLD_QUERY;
   private PreparedQuery<RowSet<Row>> SELECT_FORTUNE_QUERY;
   private PreparedQuery<RowSet<Row>> UPDATE_WORLD_QUERY;
+  private WorldCache WORLD_CACHE;
 
   public static CharSequence createDateHeader() {
     return HttpHeaders.createOptimized(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
@@ -140,10 +145,14 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
       Future<PreparedStatement> f1 = conn.prepare(SELECT_WORLD);
       Future<PreparedStatement> f2 = conn.prepare(SELECT_FORTUNE);
       Future<PreparedStatement> f3 = conn.prepare(UPDATE_WORLD);
+      Future<WorldCache> f4 = conn.preparedQuery(SELECT_WORLDS)
+          .collecting(Collectors.mapping(row -> new CachedWorld(row.getInteger(0), row.getInteger(1)), Collectors.toList()))
+          .execute().map(worlds -> new WorldCache(worlds.value()));
       f1.onSuccess(ps -> SELECT_WORLD_QUERY = ps.query());
       f2.onSuccess(ps -> SELECT_FORTUNE_QUERY = ps.query());
       f3.onSuccess(ps -> UPDATE_WORLD_QUERY = ps.query());
-      return CompositeFuture.all(f1, f2, f3);
+      f4.onSuccess(wc -> WORLD_CACHE = wc);
+      return CompositeFuture.all(f1, f2, f3, f4);
     }).onComplete(ar -> startPromise.complete());
   }
 
@@ -168,6 +177,9 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
       case PATH_FORTUNES:
         handleFortunes(request);
         break;
+      case PATH_CACHING:
+        handleCaching(request);
+        break;
       default:
         request.response().setStatusCode(404);
         request.response().end();
@@ -374,6 +386,32 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
     });
   }
 
+  private void handleCaching(HttpServerRequest req) {
+    int count = 1;
+    try {
+      String countStr = req.getParam("count");
+      if (countStr != null) {
+        count = Integer.parseInt(countStr);
+      }
+    } catch (NumberFormatException ignore) {
+    }
+    count = Math.max(1, count);
+    count = Math.min(500, count);
+    CachedWorld[] worlds = WORLD_CACHE.getCachedWorld(count);
+    JsonArray json = new JsonArray(new ArrayList<>(count));
+    for (int i = 0;i < count;i++) {
+      CachedWorld world = worlds[i];
+      json.add(JsonObject.of("id", world.getId(), "randomNumber", world.getRandomNumber()));
+    }
+    HttpServerResponse response = req.response();
+    MultiMap headers = response.headers();
+    headers
+        .add(HEADER_CONTENT_TYPE, RESPONSE_TYPE_JSON)
+        .add(HEADER_SERVER, SERVER)
+        .add(HEADER_DATE, dateString);
+    response.end(json.toBuffer(), NULL_HANDLER);
+  }
+
   public static void main(String[] args) throws Exception {
 
     int eventLoopPoolSize = VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE;

+ 34 - 0
frameworks/Java/vertx/src/main/java/vertx/model/CachedWorld.java

@@ -0,0 +1,34 @@
+package vertx.model;
+
+/**
+ * The model for the "world" database table.
+ */
+public final class CachedWorld implements Comparable<CachedWorld> {
+
+  private final int id;
+  private final int randomNumber;
+
+  /**
+   * Constructs a new world object with the given parameters.
+   *
+   * @param id the ID of the world
+   * @param randomNumber the random number of the world
+   */
+  public CachedWorld(int id, int randomNumber) {
+    this.id = id;
+    this.randomNumber = randomNumber;
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  public int getRandomNumber() {
+    return randomNumber;
+  }
+
+  @Override
+  public int compareTo(CachedWorld o) {
+    return Integer.compare(id, o.id);
+  }
+}

+ 31 - 0
frameworks/Java/vertx/src/main/java/vertx/model/WorldCache.java

@@ -0,0 +1,31 @@
+package vertx.model;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class WorldCache {
+
+    private Cache<Integer, CachedWorld> cache;
+
+    public WorldCache(List<CachedWorld> worlds) {
+        Cache<Integer, CachedWorld> cache = Caffeine.newBuilder().maximumSize(10_000).build();
+        int key = 0;
+        for (CachedWorld world : worlds) {
+            cache.put(key++, world);
+        }
+        this.cache = cache;
+    }
+
+    public CachedWorld[] getCachedWorld(int count) {
+        CachedWorld[] ret = new CachedWorld[count];
+        ThreadLocalRandom current = ThreadLocalRandom.current();
+        for (int i = 0;i < count;i++) {
+            Integer key = Integer.valueOf(current.nextInt(1000));
+            ret[i] = cache.getIfPresent(key);
+        }
+        return ret;
+    }
+}

+ 2 - 3
frameworks/Java/vertx/src/main/java/vertx/rocker/BufferRockerOutput.java

@@ -4,9 +4,8 @@ import com.fizzed.rocker.ContentType;
 import com.fizzed.rocker.RockerOutput;
 import com.fizzed.rocker.RockerOutputFactory;
 import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
 import io.vertx.core.buffer.Buffer;
-import io.vertx.core.net.impl.PartialPooledByteBufAllocator;
+import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
@@ -22,7 +21,7 @@ public class BufferRockerOutput implements RockerOutput<BufferRockerOutput> {
     };
   }
 
-  private final ByteBuf buff = PartialPooledByteBufAllocator.UNPOOLED.directBuffer();
+  private final ByteBuf buff = PartialPooledByteBufAllocator.INSTANCE.directBuffer();
   private final Buffer buffer = Buffer.buffer(buff);
   private final ContentType contentType;