Repository: aurora
Updated Branches:
  refs/heads/master e9d723d9c -> c7600955f


Add benchmarks for fetching tasks over the API.

Reviewed at https://reviews.apache.org/r/33611/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/c7600955
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/c7600955
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/c7600955

Branch: refs/heads/master
Commit: c7600955f697f12ae24885d28d3b1492574267d8
Parents: e9d723d
Author: Bill Farner <[email protected]>
Authored: Tue Apr 28 11:42:11 2015 -0700
Committer: Bill Farner <[email protected]>
Committed: Tue Apr 28 11:42:11 2015 -0700

----------------------------------------------------------------------
 build.gradle                                    |   5 +
 .../aurora/benchmark/ThriftApiBenchmarks.java   | 149 +++++++++++++------
 .../aurora/benchmark/UpdateStoreBenchmarks.java |   3 +-
 .../aurora/scheduler/storage/db/DbModule.java   |  13 +-
 .../aurora/scheduler/storage/db/DbUtil.java     |   3 +-
 .../storage/mem/InMemTaskStoreTest.java         |   3 +-
 .../aurora/scheduler/updater/JobUpdaterIT.java  |   3 +-
 7 files changed, 115 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 470d11e..4fe4a18 100644
--- a/build.gradle
+++ b/build.gradle
@@ -459,6 +459,11 @@ jacocoTestReport.finalizedBy analyzeReport
 
 def jmhHumanOutputPath = "$buildDir/reports/jmh/human.txt"
 jmh {
+  // Run specific benchmarks by passing -Pbenchmarks='<regexp' on the command 
line.  For example
+  // ./gradlew jmh -Pbenchmarks='ThriftApi.*'
+  if (project.hasProperty('benchmarks')) {
+    include = project.getProperty('benchmarks')
+  }
   jmhVersion = '1.7.1'
   jvmArgsPrepend = '-Xmx2g'
   humanOutputFile = project.file("$jmhHumanOutputPath")

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
index 6ec0e14..ed1171d 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
@@ -29,6 +29,7 @@ import com.twitter.common.util.Clock;
 import org.apache.aurora.gen.ReadOnlyScheduler;
 import org.apache.aurora.gen.Response;
 import org.apache.aurora.gen.ScheduleStatus;
+import org.apache.aurora.gen.TaskQuery;
 import org.apache.aurora.scheduler.cron.CronPredictor;
 import org.apache.aurora.scheduler.quota.QuotaManager;
 import org.apache.aurora.scheduler.state.LockManager;
@@ -78,55 +79,7 @@ public class ThriftApiBenchmarks {
 
     @Setup
     public void setUp() {
-      final TestConfiguration config =
-          new Gson().fromJson(testConfiguration, TestConfiguration.class);
-
-      Injector injector = Guice.createInjector(
-          new AbstractModule() {
-            @Override
-            protected void configure() {
-              bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK);
-              
bind(CronPredictor.class).toInstance(createThrowingFake(CronPredictor.class));
-              
bind(QuotaManager.class).toInstance(createThrowingFake(QuotaManager.class));
-              
bind(LockManager.class).toInstance(createThrowingFake(LockManager.class));
-            }
-          },
-          DbModule.testModule(Bindings.KeyFactory.PLAIN),
-          new ThriftModule.ReadOnly());
-      api = injector.getInstance(ReadOnlyScheduler.Iface.class);
-
-      // Ideally we would use the API to populate the storage, but wiring in 
the writable thrift
-      // interface requires considerably more binding setup.
-      Storage storage = injector.getInstance(Storage.class);
-      storage.write(new Storage.MutateWork.NoResult.Quiet() {
-        @Override
-        protected void execute(Storage.MutableStoreProvider storeProvider) {
-          for (int roleId = 0; roleId < config.roles; roleId++) {
-            String role = "role" + roleId;
-            for (int envId = 0; envId < config.envs; envId++) {
-              String env = "env" + envId;
-              for (int jobId = 0; jobId < config.jobs; jobId++) {
-                String job = "job" + jobId;
-                ImmutableSet.Builder<IScheduledTask> tasks = 
ImmutableSet.builder();
-                tasks.addAll(new Tasks.Builder()
-                    .setRole(role)
-                    .setEnv(env)
-                    .setJob(job)
-                    .setScheduleStatus(ScheduleStatus.RUNNING)
-                    .build(config.instances));
-                tasks.addAll(new Tasks.Builder()
-                    .setRole(role)
-                    .setEnv(env)
-                    .setJob(job)
-                    .setScheduleStatus(ScheduleStatus.FINISHED)
-                    .setUuidStart(1)
-                    .build(config.deadTasks));
-                storeProvider.getUnsafeTaskStore().saveTasks(tasks.build());
-              }
-            }
-          }
-        }
-      });
+      api = createPopulatedApi(testConfiguration);
     }
 
     @Benchmark
@@ -135,6 +88,104 @@ public class ThriftApiBenchmarks {
     }
   }
 
+  @BenchmarkMode(Mode.Throughput)
+  @OutputTimeUnit(TimeUnit.SECONDS)
+  @Warmup(iterations = 1, time = 10, timeUnit = TimeUnit.SECONDS)
+  @Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
+  @Fork(1)
+  @State(Scope.Thread)
+  public static class GetAllTasksBenchmark {
+    private ReadOnlyScheduler.Iface api;
+
+    @Param({
+        "{\"roles\": 1}",
+        "{\"roles\": 10}",
+        "{\"roles\": 100}",
+        "{\"roles\": 500}",
+        "{\"jobs\": 1}",
+        "{\"jobs\": 10}",
+        "{\"jobs\": 100}",
+        "{\"jobs\": 500}",
+        "{\"instances\": 1}",
+        "{\"instances\": 10}",
+        "{\"instances\": 100}",
+        "{\"instances\": 1000}",
+        "{\"instances\": 10000}"})
+    private String testConfiguration;
+
+    @Setup
+    public void setUp() {
+      api = createPopulatedApi(testConfiguration);
+    }
+
+    @Benchmark
+    public Response run() throws TException {
+      return api.getTasksStatus(new TaskQuery());
+    }
+  }
+
+  private static ReadOnlyScheduler.Iface createPopulatedApi(String 
testConfiguration) {
+    TestConfiguration config = new Gson().fromJson(testConfiguration, 
TestConfiguration.class);
+
+    Injector injector = createStorageInjector();
+    ReadOnlyScheduler.Iface api = 
injector.getInstance(ReadOnlyScheduler.Iface.class);
+
+    Storage storage = injector.getInstance(Storage.class);
+    storage.prepare();
+
+    bulkLoadTasks(storage, config);
+    return api;
+  }
+
+  private static Injector createStorageInjector() {
+    return Guice.createInjector(
+        new AbstractModule() {
+          @Override
+          protected void configure() {
+            bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK);
+            
bind(CronPredictor.class).toInstance(createThrowingFake(CronPredictor.class));
+            
bind(QuotaManager.class).toInstance(createThrowingFake(QuotaManager.class));
+            
bind(LockManager.class).toInstance(createThrowingFake(LockManager.class));
+          }
+        },
+        new DbModule(Bindings.KeyFactory.PLAIN),
+        new ThriftModule.ReadOnly());
+  }
+
+  private static void bulkLoadTasks(Storage storage, final TestConfiguration 
config) {
+    // Ideally we would use the API to populate the storage, but wiring in the 
writable thrift
+    // interface requires considerably more binding setup.
+    storage.bulkLoad(new Storage.MutateWork.NoResult.Quiet() {
+      @Override
+      protected void execute(Storage.MutableStoreProvider storeProvider) {
+        for (int roleId = 0; roleId < config.roles; roleId++) {
+          String role = "role" + roleId;
+          for (int envId = 0; envId < config.envs; envId++) {
+            String env = "env" + envId;
+            for (int jobId = 0; jobId < config.jobs; jobId++) {
+              String job = "job" + jobId;
+              ImmutableSet.Builder<IScheduledTask> tasks = 
ImmutableSet.builder();
+              tasks.addAll(new Tasks.Builder()
+                  .setRole(role)
+                  .setEnv(env)
+                  .setJob(job)
+                  .setScheduleStatus(ScheduleStatus.RUNNING)
+                  .build(config.instances));
+              tasks.addAll(new Tasks.Builder()
+                  .setRole(role)
+                  .setEnv(env)
+                  .setJob(job)
+                  .setScheduleStatus(ScheduleStatus.FINISHED)
+                  .setUuidStart(1)
+                  .build(config.deadTasks));
+              storeProvider.getUnsafeTaskStore().saveTasks(tasks.build());
+            }
+          }
+        }
+      }
+    });
+  }
+
   private static <T> T createThrowingFake(Class<T> clazz) {
     InvocationHandler handler = new InvocationHandler() {
       @Override

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
----------------------------------------------------------------------
diff --git 
a/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
index a4abbd8..4cc53d8 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.twitter.common.inject.Bindings;
 import com.twitter.common.util.Clock;
 
 import org.apache.aurora.gen.ExecutorConfig;
@@ -89,7 +88,7 @@ public class UpdateStoreBenchmarks {
               bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK);
             }
           },
-          DbModule.testModule(Bindings.KeyFactory.PLAIN));
+          DbModule.testModule());
       storage = injector.getInstance(Storage.class);
       storage.prepare();
     }

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
index d6ca430..c8df88b 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
@@ -22,7 +22,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Key;
 import com.google.inject.PrivateModule;
-import com.twitter.common.inject.Bindings;
+import com.twitter.common.inject.Bindings.KeyFactory;
 
 import org.apache.aurora.scheduler.storage.AttributeStore;
 import org.apache.aurora.scheduler.storage.CronJobStore;
@@ -76,29 +76,28 @@ public class DbModule extends PrivateModule {
       .add(QuotaMapper.class)
       .build();
 
-  private final Bindings.KeyFactory keyFactory;
+  private final KeyFactory keyFactory;
   private final String jdbcSchema;
 
-  private DbModule(Bindings.KeyFactory keyFactory, String jdbcSchema) {
+  private DbModule(KeyFactory keyFactory, String jdbcSchema) {
     this.keyFactory = requireNonNull(keyFactory);
     this.jdbcSchema = requireNonNull(jdbcSchema);
   }
 
-  public DbModule(Bindings.KeyFactory keyFactory) {
+  public DbModule(KeyFactory keyFactory) {
     this(keyFactory, "aurora;DB_CLOSE_DELAY=-1");
   }
 
   /**
    * Creates a module that will prepare a private in-memory database.
    *
-   * @param keyFactory Key factory to scope bindings.
    * @return A new database module for testing.
    */
   @VisibleForTesting
-  public static DbModule testModule(Bindings.KeyFactory keyFactory) {
+  public static DbModule testModule() {
     // This creates a private in-memory database.  New connections will have a 
_new_ database,
     // and closing the database will expunge its data.
-    return new DbModule(keyFactory, "");
+    return new DbModule(KeyFactory.PLAIN, "");
   }
 
   private <T> void bindStore(Class<T> binding, Class<? extends T> impl) {

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
index eae1770..a10a9e7 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
@@ -15,7 +15,6 @@ package org.apache.aurora.scheduler.storage.db;
 
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.twitter.common.inject.Bindings;
 
 import org.apache.aurora.scheduler.storage.Storage;
 
@@ -34,7 +33,7 @@ public final class DbUtil {
    * @return A new storage instance.
    */
   public static Storage createStorage() {
-    Injector injector = 
Guice.createInjector(DbModule.testModule(Bindings.KeyFactory.PLAIN));
+    Injector injector = Guice.createInjector(DbModule.testModule());
     Storage storage = injector.getInstance(Storage.class);
     storage.prepare();
     return storage;

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/test/java/org/apache/aurora/scheduler/storage/mem/InMemTaskStoreTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/aurora/scheduler/storage/mem/InMemTaskStoreTest.java 
b/src/test/java/org/apache/aurora/scheduler/storage/mem/InMemTaskStoreTest.java
index 2014b73..f18619a 100644
--- 
a/src/test/java/org/apache/aurora/scheduler/storage/mem/InMemTaskStoreTest.java
+++ 
b/src/test/java/org/apache/aurora/scheduler/storage/mem/InMemTaskStoreTest.java
@@ -15,7 +15,6 @@ package org.apache.aurora.scheduler.storage.mem;
 
 import com.google.inject.Module;
 import com.google.inject.util.Modules;
-import com.twitter.common.inject.Bindings.KeyFactory;
 
 import org.apache.aurora.scheduler.storage.AbstractTaskStoreTest;
 import org.apache.aurora.scheduler.storage.db.DbModule;
@@ -23,6 +22,6 @@ import org.apache.aurora.scheduler.storage.db.DbModule;
 public class InMemTaskStoreTest extends AbstractTaskStoreTest {
   @Override
   protected Module getStorageModule() {
-    return Modules.combine(DbModule.testModule(KeyFactory.PLAIN));
+    return Modules.combine(DbModule.testModule());
   }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/c7600955/src/test/java/org/apache/aurora/scheduler/updater/JobUpdaterIT.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/aurora/scheduler/updater/JobUpdaterIT.java 
b/src/test/java/org/apache/aurora/scheduler/updater/JobUpdaterIT.java
index 010e75f..4e7ff3b 100644
--- a/src/test/java/org/apache/aurora/scheduler/updater/JobUpdaterIT.java
+++ b/src/test/java/org/apache/aurora/scheduler/updater/JobUpdaterIT.java
@@ -33,7 +33,6 @@ import com.google.common.eventbus.EventBus;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.twitter.common.inject.Bindings.KeyFactory;
 import com.twitter.common.quantity.Amount;
 import com.twitter.common.quantity.Time;
 import com.twitter.common.stats.Stats;
@@ -171,7 +170,7 @@ public class JobUpdaterIT extends EasyMockTest {
 
     Injector injector = Guice.createInjector(
         new UpdaterModule(executor),
-        DbModule.testModule(KeyFactory.PLAIN),
+        DbModule.testModule(),
         new AbstractModule() {
           @Override
           protected void configure() {

Reply via email to