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() {
