aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wfar...@apache.org
Subject aurora git commit: Add a benchmark for getRoleSummary.
Date Fri, 03 Apr 2015 18:27:00 GMT
Repository: aurora
Updated Branches:
  refs/heads/master a7b95d95b -> 1fdb7e32c


Add a benchmark for getRoleSummary.

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


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

Branch: refs/heads/master
Commit: 1fdb7e32cde55ad08631e686328ea1d3414ea9fb
Parents: a7b95d9
Author: Bill Farner <wfarner@apache.org>
Authored: Fri Apr 3 11:26:22 2015 -0700
Committer: Bill Farner <wfarner@apache.org>
Committed: Fri Apr 3 11:26:22 2015 -0700

----------------------------------------------------------------------
 build.gradle                                    |  11 +-
 .../aurora/benchmark/SchedulingBenchmarks.java  |  17 +-
 .../java/org/apache/aurora/benchmark/Tasks.java |  19 ++-
 .../aurora/benchmark/ThriftApiBenchmarks.java   | 161 +++++++++++++++++++
 .../aurora/scheduler/thrift/ThriftModule.java   |  12 +-
 5 files changed, 201 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/1fdb7e32/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 66dbdfd..d310e82 100644
--- a/build.gradle
+++ b/build.gradle
@@ -459,17 +459,10 @@ jacocoTestReport.finalizedBy analyzeReport
 
 def jmhHumanOutputPath = "$buildDir/reports/jmh/human.txt"
 jmh {
-  jmhVersion = '1.6.1'
-  jvmArgsPrepend = '-Xmx1024m'
+  jmhVersion = '1.7.1'
+  jvmArgsPrepend = '-Xmx2g'
   humanOutputFile = project.file("$jmhHumanOutputPath")
   resultsFile = project.file("$buildDir/reports/jmh/results.txt")
-
-  // JMH run configuration parameters.
-  iterations = 100
-  fork = 1
-  warmupIterations = 10
-  benchmarkMode = 'avgt'
-  timeUnit = 'ns'
 }
 tasks.getByName('jmh').doLast() {
   println "Benchmark report generated: file://$jmhHumanOutputPath"

http://git-wip-us.apache.org/repos/asf/aurora/blob/1fdb7e32/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java b/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
index 75a67dc..88850d6 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
@@ -16,6 +16,7 @@ package org.apache.aurora.benchmark;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import javax.inject.Singleton;
 
@@ -64,10 +65,16 @@ import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.mem.MemStorage;
 import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
 import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 
 /**
  * Performance benchmarks for the task scheduling loop.
@@ -77,6 +84,11 @@ public class SchedulingBenchmarks {
   /**
    * Constructs scheduler objects and populates offers/tasks for the benchmark run.
    */
+  @BenchmarkMode(Mode.Throughput)
+  @OutputTimeUnit(TimeUnit.SECONDS)
+  @Warmup(iterations=1, time=10, timeUnit=TimeUnit.SECONDS)
+  @Measurement(iterations=10, time=10, timeUnit=TimeUnit.SECONDS)
+  @Fork(1)
   @State(Scope.Thread)
   public abstract static class AbstractBase {
     private static final Amount<Long, Time> NO_DELAY = Amount.of(0L, Time.MILLISECONDS);
@@ -241,7 +253,6 @@ public class SchedulingBenchmarks {
           .setTask(Iterables.getOnlyElement(new Tasks.Builder()
               .setProduction(true)
               .setCpu(32)
-              .setTaskIdFormat("test-%s")
               .build(1))).build();
     }
   }
@@ -257,7 +268,6 @@ public class SchedulingBenchmarks {
           .setTask(Iterables.getOnlyElement(new Tasks.Builder()
               .setProduction(true)
               .addValueConstraint("host", "denied")
-              .setTaskIdFormat("test-%s")
               .build(1))).build();
     }
   }
@@ -273,7 +283,6 @@ public class SchedulingBenchmarks {
           .setTask(Iterables.getOnlyElement(new Tasks.Builder()
               .setProduction(true)
               .addLimitConstraint("host", 0)
-              .setTaskIdFormat("test-%s")
               .build(1))).build();
     }
   }
@@ -292,7 +301,6 @@ public class SchedulingBenchmarks {
           .setTask(Iterables.getOnlyElement(new Tasks.Builder()
               .setProduction(true)
               .addLimitConstraint("host", 0)
-              .setTaskIdFormat("test-%s")
               .build(1))).build();
     }
   }
@@ -310,7 +318,6 @@ public class SchedulingBenchmarks {
           .setTask(Iterables.getOnlyElement(new Tasks.Builder()
               .setProduction(true)
               .addValueConstraint("host", "denied")
-              .setTaskIdFormat("test-%s")
               .build(1))).build();
     }
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/1fdb7e32/src/jmh/java/org/apache/aurora/benchmark/Tasks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/Tasks.java b/src/jmh/java/org/apache/aurora/benchmark/Tasks.java
index 491c687..23827ab 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/Tasks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/Tasks.java
@@ -49,7 +49,7 @@ final class Tasks {
     private static final String USER_FORMAT = "user-%s";
 
     private JobKey jobKey = new JobKey("jmh", "dev", "benchmark");
-    private String taskIdFormat = "default_task-%s";
+    private int uuidStart = 0;
     private boolean isProduction = false;
     private double cpu = 6.0;
     private Amount<Long, Data> ram = Amount.of(8L, Data.GB);
@@ -62,8 +62,18 @@ final class Tasks {
       return this;
     }
 
-    Builder setTaskIdFormat(String newTaskIdFormat) {
-      taskIdFormat = newTaskIdFormat;
+    Builder setEnv(String env) {
+      jobKey.setEnvironment(env);
+      return this;
+    }
+
+    Builder setJob(String job) {
+      jobKey.setName(job);
+      return this;
+    }
+
+    Builder setUuidStart(int uuidStart) {
+      this.uuidStart = uuidStart;
       return this;
     }
 
@@ -121,7 +131,8 @@ final class Tasks {
       ImmutableSet.Builder<IScheduledTask> tasks = ImmutableSet.builder();
 
       for (int i = 0; i < count; i++) {
-        String taskId = String.format(taskIdFormat, i);
+        String taskId =
+            jobKey.getRole() + "-" + jobKey.getEnvironment() + "-" + i + "-" + (uuidStart
+ i);
 
         tasks.add(IScheduledTask.build(new ScheduledTask()
             .setTaskEvents(Lists.newArrayList(new TaskEvent(0, ScheduleStatus.PENDING)))

http://git-wip-us.apache.org/repos/asf/aurora/blob/1fdb7e32/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
new file mode 100644
index 0000000..df053e2
--- /dev/null
+++ b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
@@ -0,0 +1,161 @@
+/**
+ * Licensed 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.aurora.benchmark;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.gson.Gson;
+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.ReadOnlyScheduler;
+import org.apache.aurora.gen.Response;
+import org.apache.aurora.gen.ScheduleStatus;
+import org.apache.aurora.scheduler.cron.CronPredictor;
+import org.apache.aurora.scheduler.quota.QuotaManager;
+import org.apache.aurora.scheduler.state.LockManager;
+import org.apache.aurora.scheduler.storage.Storage;
+import org.apache.aurora.scheduler.storage.db.DbModule;
+import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
+import org.apache.aurora.scheduler.storage.mem.MemStorage;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
+import org.apache.aurora.scheduler.thrift.ThriftModule;
+import org.apache.thrift.TException;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+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;
+import org.openjdk.jmh.annotations.Warmup;
+
+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 GetRoleSummaryBenchmark {
+    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() {
+      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));
+            }
+          },
+          new MemStorageModule(Bindings.KeyFactory.PLAIN),
+          new DbModule(Bindings.annotatedKeyFactory(MemStorage.Delegated.class)),
+          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());
+              }
+            }
+          }
+        }
+      });
+    }
+
+    @Benchmark
+    public Response run() throws TException {
+      return api.getRoleSummary();
+    }
+  }
+
+  private static <T> T createThrowingFake(Class<T> clazz) {
+    InvocationHandler handler = new InvocationHandler() {
+      @Override
+      public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
+        throw new UnsupportedOperationException("This fake has no behavior.");
+      }
+    };
+
+    @SuppressWarnings("unchecked")
+    T proxy = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, handler);
+    return proxy;
+  }
+
+  private static class TestConfiguration {
+    private int roles = 1;
+    private int envs = 5;
+    private int jobs = 1;
+    private int instances = 100;
+    private int deadTasks = 100;
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/1fdb7e32/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java b/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
index c65e021..bd92ff7 100644
--- a/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
@@ -27,7 +27,7 @@ public class ThriftModule extends AbstractModule {
 
   @Override
   protected void configure() {
-    bind(ReadOnlyScheduler.Iface.class).to(ReadOnlySchedulerImpl.class);
+    install(new ReadOnly());
     bind(AuroraAdmin.Iface.class).to(SchedulerThriftInterface.class);
     bind(AnnotatedAuroraAdmin.class).to(SchedulerThriftInterface.class);
 
@@ -36,4 +36,14 @@ public class ThriftModule extends AbstractModule {
     bind(SchedulerThriftInterface.class);
     install(new AopModule());
   }
+
+  /**
+   * Binding module for only the read-only scheduler interface.
+   */
+  public static class ReadOnly extends AbstractModule {
+    @Override
+    protected void configure() {
+      bind(ReadOnlyScheduler.Iface.class).to(ReadOnlySchedulerImpl.class);
+    }
+  }
 }


Mime
View raw message