Exclusively use Map-based in-memory stores for primary storage This patch introduces map-based volatile stores, most of which were revived from git history with minimal changes. The DB storage system is now only used in a temporary storage when replaying a snapshot containing the `dbScript` field.
Note that this change removes the transactional nature of in-memory storage operations as well as the `READ COMMITTED` transaction isolation previously available to some stores (proven in necessary changes to `StorageTransactionTest`). This means some stores will permit dirty reads when they previously did not. `TaskStore` has always had this non-transactional behavior by default, as the DB task store was never deemed suitable for production. Nonetheless, this non-transactional behavior should be considered safe as the scheduler fails over on a storage operation failure, and relies on the persistent log storage for transaction atomicity. Reviewed at https://reviews.apache.org/r/62869/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/f2755e1c Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/f2755e1c Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/f2755e1c Branch: refs/heads/master Commit: f2755e1cdd67f3c1516726c21d6e8f13059a5a01 Parents: 38476ab Author: Bill Farner <[email protected]> Authored: Tue Oct 24 23:34:09 2017 -0700 Committer: Bill Farner <[email protected]> Committed: Tue Oct 24 23:34:09 2017 -0700 ---------------------------------------------------------------------- RELEASE-NOTES.md | 12 + .../thrift/org/apache/aurora/gen/storage.thrift | 3 +- docs/reference/scheduler-configuration.md | 20 - .../upstart/aurora-scheduler-kerberos.conf | 1 - examples/vagrant/upstart/aurora-scheduler.conf | 2 - .../aurora/benchmark/SchedulingBenchmarks.java | 4 +- .../aurora/benchmark/SnapshotBenchmarks.java | 13 +- .../benchmark/StateManagerBenchmarks.java | 5 +- .../aurora/benchmark/StatusUpdateBenchmark.java | 4 +- .../aurora/benchmark/TaskStoreBenchmarks.java | 23 +- .../aurora/benchmark/ThriftApiBenchmarks.java | 5 +- .../aurora/benchmark/UpdateStoreBenchmarks.java | 8 +- .../aurora/scheduler/app/SchedulerMain.java | 10 +- .../aurora/scheduler/config/CliOptions.java | 4 - .../scheduler/http/JettyServerModule.java | 1 - .../scheduler/storage/JobUpdateStore.java | 16 + .../aurora/scheduler/storage/Storage.java | 21 +- .../apache/aurora/scheduler/storage/Util.java | 45 + .../storage/backup/TemporaryStorage.java | 22 +- .../scheduler/storage/db/DbJobUpdateStore.java | 16 +- .../aurora/scheduler/storage/db/DbModule.java | 72 +- .../aurora/scheduler/storage/db/DbStorage.java | 13 +- .../aurora/scheduler/storage/db/DbUtil.java | 12 - .../scheduler/storage/log/LogStorageModule.java | 20 +- .../storage/log/SnapshotStoreImpl.java | 208 +--- .../storage/log/WriteAheadStorage.java | 6 - .../storage/mem/InMemStoresModule.java | 65 -- .../storage/mem/MemAttributeStore.java | 82 ++ .../storage/mem/MemJobUpdateStore.java | 396 +++++++ .../scheduler/storage/mem/MemLockStore.java | 72 ++ .../scheduler/storage/mem/MemQuotaStore.java | 56 + .../storage/mem/MemSchedulerStore.java | 38 + .../scheduler/storage/mem/MemStorage.java | 103 ++ .../scheduler/storage/mem/MemStorageModule.java | 107 ++ .../aurora/scheduler/storage/mem/Util.java | 47 - .../updater/JobUpdateControllerImpl.java | 12 +- .../aurora/scheduler/app/SchedulerIT.java | 2 +- .../scheduler/app/local/LocalSchedulerMain.java | 11 - .../scheduler/config/CommandLineTest.java | 19 - .../cron/quartz/AuroraCronJobTest.java | 8 +- .../aurora/scheduler/cron/quartz/CronIT.java | 4 +- .../cron/quartz/CronJobManagerImplTest.java | 4 +- .../aurora/scheduler/http/MaintenanceTest.java | 4 +- .../scheduling/TaskSchedulerImplTest.java | 4 +- .../scheduler/state/LockManagerImplTest.java | 4 +- .../scheduler/state/StateManagerImplTest.java | 4 +- .../scheduler/stats/ResourceCounterTest.java | 4 +- .../storage/AbstractAttributeStoreTest.java | 176 +++ .../storage/AbstractJobUpdateStoreTest.java | 1046 ++++++++++++++++++ .../storage/AbstractLockStoreTest.java | 200 ++++ .../storage/AbstractQuotaStoreTest.java | 111 ++ .../storage/AbstractSchedulerStoreTest.java | 54 + .../scheduler/storage/backup/RecoveryTest.java | 8 +- .../storage/db/AttributeStoreTest.java | 24 + .../scheduler/storage/db/CronJobStoreTest.java | 39 + .../storage/db/DbAttributeStoreTest.java | 175 --- .../storage/db/DbCronJobStoreTest.java | 39 - .../storage/db/DbJobUpdateStoreTest.java | 1046 ------------------ .../scheduler/storage/db/DbLockStoreTest.java | 199 ---- .../scheduler/storage/db/DbQuotaStoreTest.java | 110 -- .../storage/db/DbSchedulerStoreTest.java | 53 - .../scheduler/storage/db/DbTaskStoreTest.java | 39 - .../storage/db/JobUpdateStoreTest.java | 25 + .../scheduler/storage/db/LockStoreTest.java | 24 + .../scheduler/storage/db/QuotaStoreTest.java | 24 + .../storage/db/SchedulerStoreTest.java | 24 + .../scheduler/storage/db/TaskStoreTest.java | 39 + .../storage/log/SnapshotStoreImplIT.java | 179 ++- .../storage/mem/InMemTaskStoreTest.java | 73 -- .../storage/mem/MemAttributeStoreTest.java | 24 + .../storage/mem/MemCronJobStoreTest.java | 7 +- .../storage/mem/MemJobUpdateStoreTest.java | 38 + .../scheduler/storage/mem/MemLockStoreTest.java | 24 + .../storage/mem/MemQuotaStoreTest.java | 24 + .../scheduler/storage/mem/MemStorageTest.java | 173 +++ .../scheduler/storage/mem/MemTaskStoreTest.java | 68 ++ .../storage/mem/StorageTransactionTest.java | 22 +- .../aurora/scheduler/thrift/ThriftIT.java | 4 +- .../aurora/scheduler/updater/JobUpdaterIT.java | 4 +- 79 files changed, 3290 insertions(+), 2417 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/RELEASE-NOTES.md ---------------------------------------------------------------------- diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 76bf868..bc11e3b 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -20,6 +20,7 @@ - Added scheduler command line argument `-hold_offers_forever`, suitable for use in clusters where Aurora is the only framework. This setting disables other options such as `-min_offer_hold_time`, and allows the scheduler to more efficiently cache scheduling attempts. +- The schduler no longer uses an internal H2 database for storage. ### Deprecations and removals: @@ -31,6 +32,17 @@ - Removed the Job environment validation from the command line client. Validation was moved to the the scheduler side through the `allowed_job_environments` option. By default allowing any of `devel`, `test`, `production`, and any value matching the regular expression `staging[0-9]*`. +- Removed scheduler command line arguments related to the internal H2 database, which is no longer + used: + - `-use_beta_db_task_store` + - `-enable_db_metrics` + - `-slow_query_log_threshold` + - `-db_row_gc_interval` + - `-db_lock_timeout` + - `-db_max_active_connection_count` + - `-db_max_idle_connection_count` + - `-snapshot_hydrate_stores` + - `-enable_h2_console` 0.18.0 ====== http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/api/src/main/thrift/org/apache/aurora/gen/storage.thrift ---------------------------------------------------------------------- diff --git a/api/src/main/thrift/org/apache/aurora/gen/storage.thrift b/api/src/main/thrift/org/apache/aurora/gen/storage.thrift index 9ee9eff..ccb5825 100644 --- a/api/src/main/thrift/org/apache/aurora/gen/storage.thrift +++ b/api/src/main/thrift/org/apache/aurora/gen/storage.thrift @@ -145,8 +145,7 @@ struct Snapshot { 9: set<api.Lock> locks 10: set<StoredJobUpdateDetails> jobUpdateDetails 11: list<string> dbScript - // Indicates if experimental DB store for tasks and cron jobs was enabled when snapshot was cut. - 12: bool experimentalTaskStore + //12: removed } // A message header that calls out the number of expected FrameChunks to follow to form a complete http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/docs/reference/scheduler-configuration.md ---------------------------------------------------------------------- diff --git a/docs/reference/scheduler-configuration.md b/docs/reference/scheduler-configuration.md index 44ba389..d17541f 100644 --- a/docs/reference/scheduler-configuration.md +++ b/docs/reference/scheduler-configuration.md @@ -16,10 +16,6 @@ Required flags: Directory to store backups under. Will be created if it does not exist. -cluster_name [not null] Name to identify the cluster being served. --db_max_active_connection_count [must be > 0] - Max number of connections to use with database via MyBatis --db_max_idle_connection_count [must be > 0] - Max number of idle connections to the database via MyBatis -framework_authentication_file Properties file which contains framework credentials to authenticate with Mesosmaster. Must contain the properties 'aurora_authentication_principal' and 'aurora_authentication_secret'. -ip @@ -72,10 +68,6 @@ Optional flags: TimeZone to use for cron predictions. -custom_executor_config [file must exist, file must be readable] Path to custom executor settings configuration file. --db_lock_timeout (default (1, mins)) - H2 table lock timeout --db_row_gc_interval (default (2, hrs)) - Interval on which to scan the database for unused row references. -default_docker_parameters (default {}) Default docker parameters for any job that does not explicitly declare parameters. -dlog_max_entry_size (default (512, KB)) @@ -86,10 +78,6 @@ Optional flags: Specifies the frequency at which snapshots of local storage are taken and written to the log. -enable_cors_for List of domains for which CORS support should be enabled. --enable_db_metrics (default true) - Whether to use MyBatis interceptor to measure the timing of intercepted Statements. --enable_h2_console (default false) - Enable H2 DB management console. -enable_mesos_fetcher (default false) Allow jobs to pass URIs to the Mesos Fetcher. Note that enabling this feature could pose a privilege escalation threat. -enable_preemptor (default true) @@ -228,12 +216,6 @@ Optional flags: Metric categories collected for production tasks. -sla_stat_refresh_interval (default (1, mins)) The SLA stat refresh interval. --slow_query_log_threshold (default (25, ms)) - Log all queries that take at least this long to execute. --slow_query_log_threshold (default (25, ms)) - Log all queries that take at least this long to execute. --snapshot_hydrate_stores (default [locks, hosts, quota, job_updates]) - Which H2-backed stores to fully hydrate on the Snapshot. -stat_retention_period (default (1, hrs)) Time for a stat to be retained in memory before expiring. -stat_sampling_interval (default (1, secs)) @@ -254,8 +236,6 @@ Optional flags: Additional Guice modules for intercepting Thrift method calls. -transient_task_state_timeout (default (5, mins)) The amount of time after which to treat a task stuck in a transient state as LOST. --use_beta_db_task_store (default false) - Whether to use the experimental database-backed task store. -viz_job_url_prefix (default ) URL prefix for job container stats. -zk_chroot_path http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/examples/vagrant/upstart/aurora-scheduler-kerberos.conf ---------------------------------------------------------------------- diff --git a/examples/vagrant/upstart/aurora-scheduler-kerberos.conf b/examples/vagrant/upstart/aurora-scheduler-kerberos.conf index 04e3d31..26b0241 100644 --- a/examples/vagrant/upstart/aurora-scheduler-kerberos.conf +++ b/examples/vagrant/upstart/aurora-scheduler-kerberos.conf @@ -52,6 +52,5 @@ exec bin/aurora-scheduler \ -http_authentication_mechanism=NEGOTIATE \ -kerberos_server_keytab=/home/vagrant/krb5-1.13.1/build/testdir/HTTP-aurora.local.keytab \ -kerberos_server_principal=HTTP/[email protected] \ - -enable_h2_console=true \ -tier_config=/home/vagrant/aurora/src/main/resources/org/apache/aurora/scheduler/tiers.json \ -offer_filter_duration=0secs http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/examples/vagrant/upstart/aurora-scheduler.conf ---------------------------------------------------------------------- diff --git a/examples/vagrant/upstart/aurora-scheduler.conf b/examples/vagrant/upstart/aurora-scheduler.conf index 63fcc87..5ca3cae 100644 --- a/examples/vagrant/upstart/aurora-scheduler.conf +++ b/examples/vagrant/upstart/aurora-scheduler.conf @@ -44,9 +44,7 @@ exec bin/aurora-scheduler \ -thermos_executor_flags="--announcer-ensemble localhost:2181 --announcer-zookeeper-auth-config /home/vagrant/aurora/examples/vagrant/config/announcer-auth.json --mesos-containerizer-path=/usr/libexec/mesos/mesos-containerizer" \ -allowed_container_types=MESOS,DOCKER \ -http_authentication_mechanism=BASIC \ - -use_beta_db_task_store=true \ -shiro_ini_path=etc/shiro.example.ini \ - -enable_h2_console=true \ -tier_config=/home/vagrant/aurora/src/main/resources/org/apache/aurora/scheduler/tiers.json \ -mesos_role=aurora-role \ -populate_discovery_info=true \ http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/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 5a9099b..e0ec793 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java @@ -69,10 +69,10 @@ import org.apache.aurora.scheduler.scheduling.TaskScheduler.TaskSchedulerImpl.Re import org.apache.aurora.scheduler.state.StateModule; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult; -import org.apache.aurora.scheduler.storage.db.DbUtil; import org.apache.aurora.scheduler.storage.entities.IHostAttributes; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.IServerInfo; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.aurora.scheduler.updater.UpdateAgentReserver; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -116,7 +116,7 @@ public class SchedulingBenchmarks { */ @Setup(Level.Trial) public void setUpBenchmark() { - storage = DbUtil.createFlaggedStorage(); + storage = MemStorageModule.newEmptyStorage(); eventBus = new EventBus(); final FakeClock clock = new FakeClock(); clock.setNowMillis(System.currentTimeMillis()); http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java ---------------------------------------------------------------------- diff --git a/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java b/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java index ae59f3d..755582d 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java @@ -17,22 +17,18 @@ import java.util.concurrent.TimeUnit; import javax.inject.Singleton; -import com.google.common.base.Optional; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; -import com.google.inject.TypeLiteral; import org.apache.aurora.benchmark.fakes.FakeStatsProvider; -import org.apache.aurora.common.inject.Bindings; import org.apache.aurora.common.stats.StatsProvider; import org.apache.aurora.common.util.Clock; import org.apache.aurora.gen.storage.Snapshot; import org.apache.aurora.scheduler.storage.Storage; -import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl; -import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.ExperimentalTaskStore; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.thrift.TException; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -85,7 +81,6 @@ public class SnapshotBenchmarks { } private SnapshotStoreImpl getSnapshotStore() { - Bindings.KeyFactory keyFactory = Bindings.annotatedKeyFactory(Storage.Volatile.class); Injector injector = Guice.createInjector( new AbstractModule() { @Override @@ -93,13 +88,9 @@ public class SnapshotBenchmarks { bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK); bind(StatsProvider.class).toInstance(new FakeStatsProvider()); bind(SnapshotStoreImpl.class).in(Singleton.class); - bind(new TypeLiteral<Boolean>() { }).annotatedWith(ExperimentalTaskStore.class) - .toInstance(true); } }, - DbModule.testModuleWithWorkQueue( - keyFactory, - Optional.of(new DbModule.TaskStoreModule(keyFactory)))); + new MemStorageModule()); storage = injector.getInstance(Key.get(Storage.class, Storage.Volatile.class)); storage.prepare(); http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java ---------------------------------------------------------------------- diff --git a/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java b/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java index c293a9f..539393f 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java @@ -26,7 +26,6 @@ import com.google.inject.Injector; import org.apache.aurora.benchmark.fakes.FakeDriver; import org.apache.aurora.benchmark.fakes.FakeEventSink; import org.apache.aurora.benchmark.fakes.FakeRescheduleCalculator; -import org.apache.aurora.common.inject.Bindings; import org.apache.aurora.common.stats.StatsProvider; import org.apache.aurora.common.util.Clock; import org.apache.aurora.gen.ScheduleStatus; @@ -39,9 +38,9 @@ import org.apache.aurora.scheduler.state.StateManager; import org.apache.aurora.scheduler.state.StateManagerImpl; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.TaskStore; -import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.ITaskConfig; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.aurora.scheduler.testing.FakeStatsProvider; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -185,7 +184,7 @@ public class StateManagerBenchmarks { bind(StatsProvider.class).toInstance(new FakeStatsProvider()); } }, - DbModule.productionModule(Bindings.KeyFactory.PLAIN, new DbModule.Options()), + new MemStorageModule(), // This is needed for storage new AsyncModule(new AsyncModule.Options()) ); http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java ---------------------------------------------------------------------- diff --git a/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java b/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java index 45c2ab9..0c31c4a 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java +++ b/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java @@ -75,9 +75,9 @@ import org.apache.aurora.scheduler.scheduling.RescheduleCalculator; import org.apache.aurora.scheduler.state.StateModule; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult; -import org.apache.aurora.scheduler.storage.db.DbUtil; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.IServerInfo; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.mesos.Scheduler; import org.apache.mesos.v1.Protos; import org.openjdk.jmh.annotations.Benchmark; @@ -177,7 +177,7 @@ public class StatusUpdateBenchmark { @Setup(Level.Trial) public void setUpBenchmark() { eventBus = new EventBus(); - storage = new SlowStorageWrapper(DbUtil.createStorage()); + storage = new SlowStorageWrapper(MemStorageModule.newEmptyStorage()); Injector injector = Guice.createInjector( new StateModule(new CliOptions()), http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java ---------------------------------------------------------------------- diff --git a/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java b/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java index f5e44df..6f2f9f4 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java @@ -16,7 +16,7 @@ package org.apache.aurora.benchmark; import java.util.Set; import java.util.concurrent.TimeUnit; -import com.google.common.base.Optional; +import com.google.common.collect.Iterables; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.util.Modules; @@ -27,10 +27,9 @@ import org.apache.aurora.common.util.testing.FakeClock; import org.apache.aurora.scheduler.base.Query; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.TaskStore; -import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.db.DbUtil; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; -import org.apache.aurora.scheduler.storage.mem.InMemStoresModule; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.aurora.scheduler.testing.FakeStatsProvider; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -46,8 +45,6 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Warmup; -import static org.apache.aurora.common.inject.Bindings.KeyFactory.PLAIN; - public class TaskStoreBenchmarks { @BenchmarkMode(Mode.Throughput) @@ -85,9 +82,7 @@ public class TaskStoreBenchmarks { public void setUp() { storage = Guice.createInjector( Modules.combine( - DbModule.testModuleWithWorkQueue( - PLAIN, - Optional.of(new InMemStoresModule(new DbModule.Options(), PLAIN))), + new MemStorageModule(), new AbstractModule() { @Override protected void configure() { @@ -110,8 +105,10 @@ public class TaskStoreBenchmarks { } @Benchmark - public Iterable<IScheduledTask> run() { - return storage.read(store -> store.getTaskStore().fetchTasks(Query.unscoped())); + public int run() { + // Iterate through results in case the result is lazily computed. + return Iterables.size( + storage.read(store -> store.getTaskStore().fetchTasks(Query.unscoped()))); } } @@ -133,8 +130,10 @@ public class TaskStoreBenchmarks { } @Benchmark - public Iterable<IScheduledTask> run() { - return storage.read(store -> store.getTaskStore().fetchTasks(Query.unscoped())); + public int run() { + // Iterate through results in case the result is lazily computed. + return Iterables.size( + storage.read(store -> store.getTaskStore().fetchTasks(Query.unscoped()))); } } } http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/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 7b40506..7ccdb11 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java @@ -24,7 +24,6 @@ import com.google.inject.Guice; import com.google.inject.Injector; import org.apache.aurora.benchmark.fakes.FakeStatsProvider; -import org.apache.aurora.common.inject.Bindings; import org.apache.aurora.common.stats.StatsProvider; import org.apache.aurora.common.util.Clock; import org.apache.aurora.gen.ReadOnlyScheduler; @@ -38,8 +37,8 @@ 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.MemStorageModule; import org.apache.aurora.scheduler.thrift.ThriftModule; import org.apache.thrift.TException; import org.openjdk.jmh.annotations.Benchmark; @@ -155,7 +154,7 @@ public class ThriftApiBenchmarks { } }, new AsyncModule(new AsyncModule.Options()), - DbModule.productionModule(Bindings.KeyFactory.PLAIN, new DbModule.Options()), + new MemStorageModule(), new ThriftModule.ReadOnly()); } http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/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 cac02a5..992e950 100644 --- a/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java +++ b/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java @@ -20,9 +20,9 @@ import com.google.common.collect.Iterables; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult; -import org.apache.aurora.scheduler.storage.db.DbUtil; import org.apache.aurora.scheduler.storage.entities.IJobUpdateDetails; import org.apache.aurora.scheduler.storage.entities.IJobUpdateKey; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.apache.thrift.TException; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -54,7 +54,7 @@ public class UpdateStoreBenchmarks { @Setup(Level.Trial) public void setUp() { - storage = DbUtil.createStorage(); + storage = MemStorageModule.newEmptyStorage(); } @Setup(Level.Iteration) @@ -94,7 +94,7 @@ public class UpdateStoreBenchmarks { @Setup(Level.Trial) public void setUp() { - storage = DbUtil.createStorage(); + storage = MemStorageModule.newEmptyStorage(); } @Setup(Level.Iteration) @@ -134,7 +134,7 @@ public class UpdateStoreBenchmarks { @Setup(Level.Trial) public void setUp() { - storage = DbUtil.createStorage(); + storage = MemStorageModule.newEmptyStorage(); } @Setup(Level.Iteration) http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java index dd0e480..7ffcf4f 100644 --- a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java +++ b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java @@ -60,12 +60,12 @@ import org.apache.aurora.scheduler.mesos.CommandLineDriverSettingsModule; import org.apache.aurora.scheduler.mesos.FrameworkInfoFactory.FrameworkInfoFactoryImpl.SchedulerProtocol; import org.apache.aurora.scheduler.mesos.LibMesosLoadingModule; import org.apache.aurora.scheduler.stats.StatsModule; -import org.apache.aurora.scheduler.storage.Storage; +import org.apache.aurora.scheduler.storage.Storage.Volatile; import org.apache.aurora.scheduler.storage.backup.BackupModule; -import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.entities.IServerInfo; import org.apache.aurora.scheduler.storage.log.LogStorageModule; import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -189,9 +189,7 @@ public class SchedulerMain { new StatsModule(options.stats), new AppModule(options), new CronModule(options.cron), - new DbModule.MigrationManagerModule(), - DbModule.productionModule(Bindings.annotatedKeyFactory(Storage.Volatile.class), options.db), - new DbModule.GarbageCollectorModule(options.db)); + new MemStorageModule(Bindings.annotatedKeyFactory(Volatile.class))); } /** @@ -277,7 +275,7 @@ public class SchedulerMain { new CommandLineDriverSettingsModule(options.driver, options.main.allowGpuResource), new LibMesosLoadingModule(options.main.driverImpl), new MesosLogStreamModule(options.mesosLog, FlaggedZooKeeperConfig.create(options.zk)), - new LogStorageModule(options.logStorage, options.db.useDbTaskStore), + new LogStorageModule(options.logStorage), new TierModule(options.tiers), new WebhookModule(options.webhook) ) http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java b/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java index 64733e5..d4537e3 100644 --- a/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java +++ b/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java @@ -29,7 +29,6 @@ import org.apache.aurora.scheduler.configuration.executor.ExecutorModule; import org.apache.aurora.scheduler.cron.quartz.CronModule; import org.apache.aurora.scheduler.discovery.FlaggedZooKeeperConfig; import org.apache.aurora.scheduler.events.WebhookModule; -import org.apache.aurora.scheduler.http.H2ConsoleModule; import org.apache.aurora.scheduler.http.JettyServerModule; import org.apache.aurora.scheduler.http.api.ApiModule; import org.apache.aurora.scheduler.http.api.security.HttpSecurityModule; @@ -48,7 +47,6 @@ import org.apache.aurora.scheduler.state.StateModule; import org.apache.aurora.scheduler.stats.AsyncStatsModule; import org.apache.aurora.scheduler.stats.StatsModule; import org.apache.aurora.scheduler.storage.backup.BackupModule; -import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.log.LogStorageModule; import org.apache.aurora.scheduler.thrift.aop.AopModule; import org.apache.aurora.scheduler.updater.UpdaterModule; @@ -65,7 +63,6 @@ public class CliOptions { public final FlaggedZooKeeperConfig.Options zk = new FlaggedZooKeeperConfig.Options(); public final UpdaterModule.Options updater = new UpdaterModule.Options(); public final StateModule.Options state = new StateModule.Options(); - public final DbModule.Options db = new DbModule.Options(); public final LogStorageModule.Options logStorage = new LogStorageModule.Options(); public final BackupModule.Options backup = new BackupModule.Options(); public final AopModule.Options aop = new AopModule.Options(); @@ -77,7 +74,6 @@ public class CliOptions { public final Kerberos5ShiroRealmModule.Options kerberos = new Kerberos5ShiroRealmModule.Options(); public final IniShiroRealmModule.Options iniShiroRealm = new IniShiroRealmModule.Options(); public final ApiModule.Options api = new ApiModule.Options(); - public final H2ConsoleModule.Options h2Console = new H2ConsoleModule.Options(); public final PreemptorModule.Options preemptor = new PreemptorModule.Options(); public final MesosLogStreamModule.Options mesosLog = new MesosLogStreamModule.Options(); public final SlaModule.Options sla = new SlaModule.Options(); http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java index 47fd92f..b19bccd 100644 --- a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java +++ b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java @@ -195,7 +195,6 @@ public class JettyServerModule extends AbstractModule { parentInjector, Modules.combine( new ApiModule(options.api), - new H2ConsoleModule(options.h2Console), new HttpSecurityModule(options), new ThriftModule(), new AopModule(options))); http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java b/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java index 254c9b7..5b57399 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java @@ -13,11 +13,13 @@ */ package org.apache.aurora.scheduler.storage; +import java.util.EnumSet; import java.util.List; import java.util.Set; import com.google.common.base.Optional; +import org.apache.aurora.gen.JobUpdateStatus; import org.apache.aurora.gen.storage.StoredJobUpdateDetails; import org.apache.aurora.scheduler.storage.entities.IJobInstanceUpdateEvent; import org.apache.aurora.scheduler.storage.entities.IJobUpdate; @@ -28,11 +30,25 @@ import org.apache.aurora.scheduler.storage.entities.IJobUpdateKey; import org.apache.aurora.scheduler.storage.entities.IJobUpdateQuery; import org.apache.aurora.scheduler.storage.entities.IJobUpdateSummary; +import static org.apache.aurora.gen.JobUpdateStatus.ABORTED; +import static org.apache.aurora.gen.JobUpdateStatus.ERROR; +import static org.apache.aurora.gen.JobUpdateStatus.FAILED; +import static org.apache.aurora.gen.JobUpdateStatus.ROLLED_BACK; +import static org.apache.aurora.gen.JobUpdateStatus.ROLLED_FORWARD; + /** * Stores all job updates and defines methods for saving, updating and fetching job updates. */ public interface JobUpdateStore { + EnumSet<JobUpdateStatus> TERMINAL_STATES = EnumSet.of( + ROLLED_FORWARD, + ROLLED_BACK, + ABORTED, + FAILED, + ERROR + ); + /** * Fetches a read-only view of job update summaries. * http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/Storage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/Storage.java b/src/main/java/org/apache/aurora/scheduler/storage/Storage.java index 6c67669..7e810ab 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/Storage.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/Storage.java @@ -32,6 +32,10 @@ import org.apache.aurora.scheduler.storage.entities.IScheduledTask; */ public interface Storage { + /** + * Provider for read-only stores. Store implementations must be thread-safe, and should support + * concurrent reads where appropriate. + */ interface StoreProvider { SchedulerStore getSchedulerStore(); CronJobStore getCronJobStore(); @@ -42,6 +46,10 @@ public interface Storage { JobUpdateStore getJobUpdateStore(); } + /** + * Provider for stores that permit mutations. Store implementations need not support concurrent + * writes, as a global reentrant write lock is used to serialize write operations. + */ interface MutableStoreProvider extends StoreProvider { SchedulerStore.Mutable getSchedulerStore(); CronJobStore.Mutable getCronJobStore(); @@ -65,19 +73,6 @@ public interface Storage { QuotaStore.Mutable getQuotaStore(); AttributeStore.Mutable getAttributeStore(); JobUpdateStore.Mutable getJobUpdateStore(); - - /** - * Gets direct low level access to the underlying storage. - * <p> - * This grants a potentially dangerous direct access to the underlying storage and should - * only be used during storage initialization when unstructured bulk data manipulations - * are required. - * </p> - * - * @param <T> Direct access type. - * @return Direct read/write accessor to the storage. - */ - <T> T getUnsafeStoreAccess(); } /** http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/Util.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/Util.java b/src/main/java/org/apache/aurora/scheduler/storage/Util.java new file mode 100644 index 0000000..01c6a8a --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/storage/Util.java @@ -0,0 +1,45 @@ +/** + * 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.scheduler.storage; + +import org.apache.aurora.gen.JobUpdateAction; +import org.apache.aurora.gen.JobUpdateStatus; + +public final class Util { + + private Util() { + // Utility class. + } + + /** + * Gets the gauge name for the running count of {@link JobUpdateAction}s. + * + * @param action Update action. + * @return Gauge name. + */ + public static String jobUpdateActionStatName(JobUpdateAction action) { + return "update_instance_transition_" + action; + } + + /** + * Gets the gauge name for the running count of {@link JobUpdateStatus}es. + * + * @param status Update status. + * @return Gauge name. + */ + public static String jobUpdateStatusStatName(JobUpdateStatus status) { + return "update_transition_" + status; + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java b/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java index bad05f5..3000796 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java @@ -17,7 +17,6 @@ import java.util.Set; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import org.apache.aurora.common.util.BuildInfo; @@ -28,11 +27,10 @@ import org.apache.aurora.scheduler.base.Tasks; import org.apache.aurora.scheduler.storage.SnapshotStore; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult; -import org.apache.aurora.scheduler.storage.db.DbUtil; -import org.apache.aurora.scheduler.storage.db.EnumBackfill; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl; import org.apache.aurora.scheduler.storage.log.ThriftBackfill; +import org.apache.aurora.scheduler.storage.mem.MemStorageModule; import static java.util.Objects.requireNonNull; @@ -72,17 +70,15 @@ interface TemporaryStorage { class TemporaryStorageFactory implements Function<Snapshot, TemporaryStorage> { private final ThriftBackfill thriftBackfill; - private final EnumBackfill enumBackfill; @Inject - TemporaryStorageFactory(ThriftBackfill thriftBackfill, EnumBackfill enumBackfill) { + TemporaryStorageFactory(ThriftBackfill thriftBackfill) { this.thriftBackfill = requireNonNull(thriftBackfill); - this.enumBackfill = requireNonNull(enumBackfill); } @Override public TemporaryStorage apply(Snapshot snapshot) { - final Storage storage = DbUtil.createFlaggedStorage(); + final Storage storage = MemStorageModule.newEmptyStorage(); final BuildInfo buildInfo = generateBuildInfo(); FakeClock clock = new FakeClock(); clock.setNowMillis(snapshot.getTimestamp()); @@ -90,17 +86,7 @@ interface TemporaryStorage { buildInfo, clock, storage, - // Safe to pass false here to default to the non-experimental task store - // during restore from backup procedure. - false /** useDbSnapshotForTaskStore */, - // Safe to pass empty set here because during backup restore we are not deciding which - // fields to write to the snapshot. - ImmutableSet.of() /** hydrateFields */, - // We can just pass an empty lambda for the MigrationManager as migration is a no-op - // when restoring from backup. - () -> { } /** migrationManager */, - thriftBackfill, - enumBackfill); + thriftBackfill); snapshotStore.applySnapshot(snapshot); return new TemporaryStorage() { http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java b/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java index df37fb7..af854da 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java @@ -19,7 +19,6 @@ import java.util.concurrent.atomic.AtomicLong; import javax.inject.Inject; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; @@ -34,6 +33,7 @@ import org.apache.aurora.gen.JobUpdateAction; import org.apache.aurora.gen.JobUpdateStatus; import org.apache.aurora.gen.storage.StoredJobUpdateDetails; import org.apache.aurora.scheduler.storage.JobUpdateStore; +import org.apache.aurora.scheduler.storage.Util; import org.apache.aurora.scheduler.storage.db.views.DbJobUpdate; import org.apache.aurora.scheduler.storage.db.views.DbJobUpdateInstructions; import org.apache.aurora.scheduler.storage.db.views.DbStoredJobUpdateDetails; @@ -84,7 +84,7 @@ public class DbJobUpdateStore implements JobUpdateStore.Mutable { .build(new CacheLoader<JobUpdateStatus, AtomicLong>() { @Override public AtomicLong load(JobUpdateStatus status) { - return statsProvider.makeCounter(jobUpdateStatusStatName(status)); + return statsProvider.makeCounter(Util.jobUpdateStatusStatName(status)); } }); for (JobUpdateStatus status : JobUpdateStatus.values()) { @@ -94,7 +94,7 @@ public class DbJobUpdateStore implements JobUpdateStore.Mutable { .build(new CacheLoader<JobUpdateAction, AtomicLong>() { @Override public AtomicLong load(JobUpdateAction action) { - return statsProvider.makeCounter(jobUpdateActionStatName(action)); + return statsProvider.makeCounter(Util.jobUpdateActionStatName(action)); } }); for (JobUpdateAction action : JobUpdateAction.values()) { @@ -165,11 +165,6 @@ public class DbJobUpdateStore implements JobUpdateStore.Mutable { } } - @VisibleForTesting - static String jobUpdateStatusStatName(JobUpdateStatus status) { - return "update_transition_" + status; - } - @Timed("job_update_store_save_event") @Override public void saveJobUpdateEvent(IJobUpdateKey key, IJobUpdateEvent event) { @@ -177,11 +172,6 @@ public class DbJobUpdateStore implements JobUpdateStore.Mutable { jobUpdateEventStats.getUnchecked(event.getStatus()).incrementAndGet(); } - @VisibleForTesting - static String jobUpdateActionStatName(JobUpdateAction action) { - return "update_instance_transition_" + action; - } - @Timed("job_update_store_save_instance_event") @Override public void saveJobInstanceUpdateEvent(IJobUpdateKey key, IJobInstanceUpdateEvent event) { http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/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 fb3dadb..7bd37f7 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 @@ -23,7 +23,6 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.AbstractScheduledService; @@ -50,7 +49,6 @@ import org.apache.aurora.scheduler.storage.SchedulerStore; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.TaskStore; import org.apache.aurora.scheduler.storage.db.typehandlers.TypeHandlers; -import org.apache.aurora.scheduler.storage.mem.InMemStoresModule; import org.apache.ibatis.migration.JavaMigrationLoader; import org.apache.ibatis.migration.MigrationLoader; import org.apache.ibatis.session.AutoMappingBehavior; @@ -71,11 +69,6 @@ public final class DbModule extends PrivateModule { @Parameters(separators = "=") public static class Options { - @Parameter(names = "-use_beta_db_task_store", - description = "Whether to use the experimental database-backed task store.", - arity = 1) - public boolean useDbTaskStore = false; - @Parameter(names = "-enable_db_metrics", description = "Whether to use MyBatis interceptor to measure the timing of intercepted Statements.", @@ -121,19 +114,16 @@ public final class DbModule extends PrivateModule { private final Options options; private final KeyFactory keyFactory; - private final Module taskStoresModule; private final String jdbcSchema; private DbModule( Options options, KeyFactory keyFactory, - Module taskStoresModule, String dbName, Map<String, String> jdbcUriArgs) { this.options = requireNonNull(options); this.keyFactory = requireNonNull(keyFactory); - this.taskStoresModule = requireNonNull(taskStoresModule); Map<String, String> args = ImmutableMap.<String, String>builder() .putAll(jdbcUriArgs) @@ -162,19 +152,16 @@ public final class DbModule extends PrivateModule { return new DbModule( options, keyFactory, - getTaskStoreModule(options, keyFactory), "aurora", ImmutableMap.of("DB_CLOSE_DELAY", "-1")); } @VisibleForTesting - public static Module testModule(KeyFactory keyFactory, Optional<Module> taskStoreModule) { + public static Module testModule(KeyFactory keyFactory) { DbModule.Options options = new DbModule.Options(); return new DbModule( options, keyFactory, - taskStoreModule.isPresent() - ? taskStoreModule.get() : getTaskStoreModule(options, keyFactory), "testdb-" + UUID.randomUUID().toString(), // A non-zero close delay is used here to avoid eager database cleanup in tests that // make use of multiple threads. Since all test databases are separately scoped by the @@ -184,14 +171,14 @@ public final class DbModule extends PrivateModule { } /** - * Same as {@link #testModuleWithWorkQueue(KeyFactory, Optional)} but with default task store and + * Same as {@link #testModuleWithWorkQueue(KeyFactory)} but with default task store and * key factory. * * @return A new database module for testing. */ @VisibleForTesting public static Module testModule() { - return testModule(KeyFactory.PLAIN, Optional.of(new TaskStoreModule(KeyFactory.PLAIN))); + return testModule(KeyFactory.PLAIN); } /** @@ -199,14 +186,10 @@ public final class DbModule extends PrivateModule { * implementation bound within the key factory and provided module. * * @param keyFactory Key factory to use. - * @param taskStoreModule Module providing task store bindings. * @return A new database module for testing. */ @VisibleForTesting - public static Module testModuleWithWorkQueue( - KeyFactory keyFactory, - Optional<Module> taskStoreModule) { - + public static Module testModuleWithWorkQueue(KeyFactory keyFactory) { return Modules.combine( new AbstractModule() { @Override @@ -222,27 +205,18 @@ public final class DbModule extends PrivateModule { }); } }, - testModule(keyFactory, taskStoreModule) + testModule(keyFactory) ); } /** - * Same as {@link #testModuleWithWorkQueue(KeyFactory, Optional)} but with default task store and - * key factory. + * Same as {@link #testModuleWithWorkQueue(KeyFactory)} but with default key factory. * * @return A new database module for testing. */ @VisibleForTesting public static Module testModuleWithWorkQueue() { - return testModuleWithWorkQueue( - KeyFactory.PLAIN, - Optional.of(new TaskStoreModule(KeyFactory.PLAIN))); - } - - private static Module getTaskStoreModule(Options options, KeyFactory keyFactory) { - return options.useDbTaskStore - ? new TaskStoreModule(keyFactory) - : new InMemStoresModule(options, keyFactory); + return testModuleWithWorkQueue(KeyFactory.PLAIN); } private <T> void bindStore(Class<T> binding, Class<? extends T> impl) { @@ -308,7 +282,6 @@ public final class DbModule extends PrivateModule { expose(JobKeyMapper.class); } }); - install(taskStoresModule); expose(keyFactory.create(CronJobStore.Mutable.class)); expose(keyFactory.create(TaskStore.Mutable.class)); @@ -317,6 +290,8 @@ public final class DbModule extends PrivateModule { bindStore(QuotaStore.Mutable.class, DbQuotaStore.class); bindStore(SchedulerStore.Mutable.class, DbSchedulerStore.class); bindStore(JobUpdateStore.Mutable.class, DbJobUpdateStore.class); + bindStore(TaskStore.Mutable.class, DbTaskStore.class); + bindStore(CronJobStore.Mutable.class, DbCronJobStore.class); Key<Storage> storageKey = keyFactory.create(Storage.class); bind(storageKey).to(DbStorage.class); @@ -335,35 +310,6 @@ public final class DbModule extends PrivateModule { } /** - * A module that binds a database task store. - * <p/> - * TODO(wfarner): Inline these bindings once there is only one task store implementation. - */ - public static class TaskStoreModule extends PrivateModule { - private final KeyFactory keyFactory; - - public TaskStoreModule(KeyFactory keyFactory) { - this.keyFactory = requireNonNull(keyFactory); - } - - private <T> void bindStore(Class<T> binding, Class<? extends T> impl) { - bind(binding).to(impl); - bind(impl).in(Singleton.class); - Key<T> key = keyFactory.create(binding); - bind(key).to(impl); - expose(key); - } - - @Override - protected void configure() { - bindStore(TaskStore.Mutable.class, DbTaskStore.class); - expose(TaskStore.Mutable.class); - bindStore(CronJobStore.Mutable.class, DbCronJobStore.class); - expose(DbCronJobStore.Mutable.class); - } - } - - /** * Module that sets up a periodic database garbage-collection routine. */ public static class GarbageCollectorModule extends AbstractModule { http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java index 7904e38..aa7c03b 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java @@ -57,7 +57,7 @@ import static org.apache.ibatis.mapping.SqlCommandType.UPDATE; * <p> * Delegates read and write concurrency semantics to the underlying database. */ -class DbStorage extends AbstractIdleService implements Storage { +public class DbStorage extends AbstractIdleService implements Storage { private final SqlSessionFactory sessionFactory; private final EnumBackfill enumBackfill; @@ -129,16 +129,15 @@ class DbStorage extends AbstractIdleService implements Storage { public JobUpdateStore.Mutable getJobUpdateStore() { return jobUpdateStore; } - - @Override - @SuppressWarnings("unchecked") - public <T> T getUnsafeStoreAccess() { - return (T) sessionFactory.getConfiguration().getEnvironment().getDataSource(); - } }; this.statsProvider = requireNonNull(statsProvider); } + @SuppressWarnings("unchecked") + public <T> T getUnsafeStoreAccess() { + return (T) sessionFactory.getConfiguration().getEnvironment().getDataSource(); + } + @Timed("db_storage_read_operation") @Override @Transactional http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/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 942d180..443b473 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 @@ -13,7 +13,6 @@ */ package org.apache.aurora.scheduler.storage.db; -import com.google.common.base.Optional; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; @@ -25,7 +24,6 @@ import org.apache.aurora.common.util.testing.FakeClock; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.testing.FakeStatsProvider; -import static org.apache.aurora.common.inject.Bindings.KeyFactory.PLAIN; import static org.apache.aurora.scheduler.storage.db.DbModule.testModuleWithWorkQueue; /** @@ -75,14 +73,4 @@ public final class DbUtil { public static Storage createStorage() { return createStorageInjector(testModuleWithWorkQueue()).getInstance(Storage.class); } - - /** - * Creates a new, empty storage system with a task store defined by the command line flag. - * - * @return A new storage instance. - */ - public static Storage createFlaggedStorage() { - return createStorageInjector(testModuleWithWorkQueue(PLAIN, Optional.absent())) - .getInstance(Storage.class); - } } http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java index 63150d0..c8dc7ad 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java @@ -13,8 +13,6 @@ */ package org.apache.aurora.scheduler.storage.log; -import java.util.Set; - import javax.inject.Singleton; import com.beust.jcommander.Parameter; @@ -36,8 +34,6 @@ import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.NonVolatileStorage; import org.apache.aurora.scheduler.storage.log.LogManager.MaxEntrySize; import org.apache.aurora.scheduler.storage.log.LogStorage.Settings; -import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.ExperimentalTaskStore; -import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.HydrateSnapshotFields; import static org.apache.aurora.scheduler.storage.log.EntrySerializer.EntrySerializerImpl; import static org.apache.aurora.scheduler.storage.log.LogManager.LogEntryHashFunction; @@ -65,18 +61,12 @@ public class LogStorageModule extends PrivateModule { "Specifies the maximum entry size to append to the log. Larger entries will be " + "split across entry Frames.") public DataAmount maxLogEntrySize = new DataAmount(512, Data.KB); - - @Parameter(names = "-snapshot_hydrate_stores", - description = "Which H2-backed stores to fully hydrate on the Snapshot.") - public Set<String> hydrateSnapshotFields = SnapshotStoreImpl.ALL_H2_STORE_FIELDS; } private final Options options; - private final boolean useDbTaskStore; - public LogStorageModule(Options options, boolean useDbTaskStore) { + public LogStorageModule(Options options) { this.options = options; - this.useDbTaskStore = useDbTaskStore; } @Override @@ -84,24 +74,16 @@ public class LogStorageModule extends PrivateModule { bind(Settings.class) .toInstance(new Settings(options.shutdownGracePeriod, options.snapshotInterval)); - bind(new TypeLiteral<Boolean>() { }).annotatedWith(ExperimentalTaskStore.class) - .toInstance(useDbTaskStore); - bind(new TypeLiteral<Amount<Integer, Data>>() { }).annotatedWith(MaxEntrySize.class) .toInstance(options.maxLogEntrySize); bind(LogManager.class).in(Singleton.class); bind(LogStorage.class).in(Singleton.class); - bind(new TypeLiteral<Set<String>>() { }).annotatedWith(HydrateSnapshotFields.class) - .toInstance(options.hydrateSnapshotFields); - install(CallOrderEnforcingStorage.wrappingModule(LogStorage.class)); bind(DistributedSnapshotStore.class).to(LogStorage.class); expose(Storage.class); expose(NonVolatileStorage.class); expose(DistributedSnapshotStore.class); - expose(new TypeLiteral<Boolean>() { }).annotatedWith(ExperimentalTaskStore.class); - expose(new TypeLiteral<Set<String>>() { }).annotatedWith(HydrateSnapshotFields.class); bind(EntrySerializer.class).to(EntrySerializerImpl.class); // TODO(ksweeney): We don't need a cryptographic checksum here - assess performance of MD5 http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java index fdf9c33..3258879 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java @@ -13,13 +13,8 @@ */ package org.apache.aurora.scheduler.storage.log; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; import java.sql.Connection; import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; import java.util.List; @@ -27,7 +22,6 @@ import java.util.Map; import java.util.Set; import javax.inject.Inject; -import javax.inject.Qualifier; import javax.sql.DataSource; import com.google.common.annotations.VisibleForTesting; @@ -36,9 +30,10 @@ import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.inject.Injector; import org.apache.aurora.common.inject.TimedInterceptor.Timed; import org.apache.aurora.common.stats.SlidingStats; @@ -62,6 +57,9 @@ import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.Storage.MutableStoreProvider; import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult; import org.apache.aurora.scheduler.storage.Storage.Volatile; +import org.apache.aurora.scheduler.storage.db.DbModule; +import org.apache.aurora.scheduler.storage.db.DbStorage; +import org.apache.aurora.scheduler.storage.db.DbUtil; import org.apache.aurora.scheduler.storage.db.EnumBackfill; import org.apache.aurora.scheduler.storage.db.MigrationManager; import org.apache.aurora.scheduler.storage.entities.IHostAttributes; @@ -95,16 +93,6 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { */ private static final int DB_BATCH_SIZE = 20; - private static boolean hasDbSnapshot(Snapshot snapshot) { - return snapshot.isSetDbScript(); - } - - private boolean hasDbTaskStore(Snapshot snapshot) { - return useDbSnapshotForTaskStore - && hasDbSnapshot(snapshot) - && snapshot.isExperimentalTaskStore(); - } - private static final String DB_SCRIPT_FIELD = "dbscript"; private static final String LOCK_FIELD = "locks"; private static final String HOST_ATTRIBUTES_FIELD = "hosts"; @@ -114,15 +102,12 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { private static final String JOB_UPDATE_FIELD = "job_updates"; private static final String SCHEDULER_METADATA_FIELD = "scheduler_metadata"; - /** - * Used by LogStorageModule to maintain legacy behavior for a change to snapshot format - * (and thus also backup processing) behavior. See AURORA-1861 for context. - */ - public static final Set<String> ALL_H2_STORE_FIELDS = ImmutableSet.of( - LOCK_FIELD, - HOST_ATTRIBUTES_FIELD, - QUOTA_FIELD, - JOB_UPDATE_FIELD); + @VisibleForTesting + Set<String> snapshotFieldNames() { + return FluentIterable.from(snapshotFields) + .transform(SnapshotField::getName) + .toSet(); + } private final Iterable<SnapshotField> snapshotFields = Arrays.asList( // Order is critical here. The DB snapshot should always be tried first to ensure @@ -143,29 +128,21 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { @Override public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { - LOG.info("Saving dbsnapshot"); - // Note: we don't use mybatis mapped statements for performance reasons and to avoid - // mapping/unmapping hassle as snapshot commands should never be used upstream. - try (Connection c = ((DataSource) store.getUnsafeStoreAccess()).getConnection()) { - try (PreparedStatement ps = c.prepareStatement("SCRIPT")) { - try (ResultSet rs = ps.executeQuery()) { - ImmutableList.Builder<String> builder = ImmutableList.builder(); - while (rs.next()) { - String columnValue = rs.getString("SCRIPT"); - builder.add(columnValue + "\n"); - } - snapshot.setDbScript(builder.build()); - } - } - } catch (SQLException e) { - throw new RuntimeException(e); - } + // No-op. } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { if (snapshot.isSetDbScript()) { - try (Connection c = ((DataSource) store.getUnsafeStoreAccess()).getConnection()) { + LOG.info("Loading contents from legacy dbScript field"); + + Injector injector = DbUtil.createStorageInjector(DbModule.testModuleWithWorkQueue()); + + DbStorage tempStorage = injector.getInstance(DbStorage.class); + MigrationManager migrationManager = injector.getInstance(MigrationManager.class); + EnumBackfill enumBackfill = injector.getInstance(EnumBackfill.class); + + try (Connection c = ((DataSource) tempStorage.getUnsafeStoreAccess()).getConnection()) { LOG.info("Dropping all tables"); try (PreparedStatement drop = c.prepareStatement("DROP ALL OBJECTS")) { drop.executeUpdate(); @@ -193,6 +170,10 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { // This ensures any subsequently added enum values since the last snapshot exist in // the db. enumBackfill.backfill(); + + // Load the contents of the DB into the main storage. + Snapshot dbSnapshot = createSnapshot(tempStorage); + applySnapshot(dbSnapshot); } } }, @@ -206,21 +187,13 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { // references to be valid on insertion. @Override public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hydrateSnapshotFields.contains(getName())) { - snapshot.setLocks(ILock.toBuildersSet(store.getLockStore().fetchLocks())); - } + snapshot.setLocks(ILock.toBuildersSet(store.getLockStore().fetchLocks())); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbSnapshot(snapshot)) { - LOG.info("Deferring lock restore to dbsnapshot"); - return; - } - - store.getLockStore().deleteLocks(); - - if (snapshot.isSetLocks()) { + if (snapshot.getLocksSize() > 0) { + store.getLockStore().deleteLocks(); for (Lock lock : snapshot.getLocks()) { store.getLockStore().saveLock(ILock.build(lock)); } @@ -235,22 +208,14 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { @Override public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hydrateSnapshotFields.contains(getName())) { - snapshot.setHostAttributes( - IHostAttributes.toBuildersSet(store.getAttributeStore().getHostAttributes())); - } + snapshot.setHostAttributes( + IHostAttributes.toBuildersSet(store.getAttributeStore().getHostAttributes())); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbSnapshot(snapshot)) { - LOG.info("Deferring attribute restore to dbsnapshot"); - return; - } - - store.getAttributeStore().deleteHostAttributes(); - - if (snapshot.isSetHostAttributes()) { + if (snapshot.getHostAttributesSize() > 0) { + store.getAttributeStore().deleteHostAttributes(); for (HostAttributes attributes : snapshot.getHostAttributes()) { store.getAttributeStore().saveHostAttributes(IHostAttributes.build(attributes)); } @@ -267,19 +232,12 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { snapshot.setTasks( IScheduledTask.toBuildersSet(store.getTaskStore().fetchTasks(Query.unscoped()))); - snapshot.setExperimentalTaskStore(useDbSnapshotForTaskStore); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbTaskStore(snapshot)) { - LOG.info("Deferring task restore to dbsnapshot"); - return; - } - - store.getUnsafeTaskStore().deleteAllTasks(); - - if (snapshot.isSetTasks()) { + if (snapshot.getTasksSize() > 0) { + store.getUnsafeTaskStore().deleteAllTasks(); store.getUnsafeTaskStore() .saveTasks(thriftBackfill.backfillTasks(snapshot.getTasks())); } @@ -299,19 +257,12 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { jobs.add(new StoredCronJob(config.newBuilder())); } snapshot.setCronJobs(jobs.build()); - snapshot.setExperimentalTaskStore(useDbSnapshotForTaskStore); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbTaskStore(snapshot)) { - LOG.info("Deferring cron job restore to dbsnapshot"); - return; - } - - store.getCronJobStore().deleteJobs(); - - if (snapshot.isSetCronJobs()) { + if (snapshot.getCronJobsSize() > 0) { + store.getCronJobStore().deleteJobs(); for (StoredCronJob job : snapshot.getCronJobs()) { store.getCronJobStore().saveAcceptedJob( thriftBackfill.backfillJobConfiguration(job.getJobConfiguration())); @@ -332,11 +283,6 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbSnapshot(snapshot)) { - LOG.info("Deferring metadata restore to dbsnapshot"); - return; - } - if (snapshot.isSetSchedulerMetadata() && snapshot.getSchedulerMetadata().isSetFrameworkId()) { // No delete necessary here since this is a single value. @@ -354,28 +300,20 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { @Override public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hydrateSnapshotFields.contains(getName())) { - ImmutableSet.Builder<QuotaConfiguration> quotas = ImmutableSet.builder(); - for (Map.Entry<String, IResourceAggregate> entry - : store.getQuotaStore().fetchQuotas().entrySet()) { + ImmutableSet.Builder<QuotaConfiguration> quotas = ImmutableSet.builder(); + for (Map.Entry<String, IResourceAggregate> entry + : store.getQuotaStore().fetchQuotas().entrySet()) { - quotas.add(new QuotaConfiguration(entry.getKey(), entry.getValue().newBuilder())); - } - - snapshot.setQuotaConfigurations(quotas.build()); + quotas.add(new QuotaConfiguration(entry.getKey(), entry.getValue().newBuilder())); } + + snapshot.setQuotaConfigurations(quotas.build()); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbSnapshot(snapshot)) { - LOG.info("Deferring quota restore to dbsnapshot"); - return; - } - - store.getQuotaStore().deleteQuotas(); - - if (snapshot.isSetQuotaConfigurations()) { + if (snapshot.getQuotaConfigurationsSize() > 0) { + store.getQuotaStore().deleteQuotas(); for (QuotaConfiguration quota : snapshot.getQuotaConfigurations()) { store.getQuotaStore() .saveQuota(quota.getRole(), IResourceAggregate.build(quota.getQuota())); @@ -391,22 +329,14 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { @Override public void saveToSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hydrateSnapshotFields.contains(getName())) { - snapshot.setJobUpdateDetails(store.getJobUpdateStore().fetchAllJobUpdateDetails()); - } + snapshot.setJobUpdateDetails(store.getJobUpdateStore().fetchAllJobUpdateDetails()); } @Override public void restoreFromSnapshot(MutableStoreProvider store, Snapshot snapshot) { - if (hasDbSnapshot(snapshot)) { - LOG.info("Deferring job update restore to dbsnapshot"); - return; - } - - JobUpdateStore.Mutable updateStore = store.getJobUpdateStore(); - updateStore.deleteAllUpdatesAndEvents(); - - if (snapshot.isSetJobUpdateDetails()) { + if (snapshot.getJobUpdateDetailsSize() > 0) { + JobUpdateStore.Mutable updateStore = store.getJobUpdateStore(); + updateStore.deleteAllUpdatesAndEvents(); for (StoredJobUpdateDetails storedDetails : snapshot.getJobUpdateDetails()) { JobUpdateDetails details = storedDetails.getDetails(); updateStore.saveJobUpdate( @@ -437,55 +367,25 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { private final BuildInfo buildInfo; private final Clock clock; private final Storage storage; - private final boolean useDbSnapshotForTaskStore; - private final Set<String> hydrateSnapshotFields; - private final MigrationManager migrationManager; private final ThriftBackfill thriftBackfill; - private final EnumBackfill enumBackfill; - - /** - * Identifies if experimental task store is in use. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.PARAMETER, ElementType.METHOD }) - @Qualifier - public @interface ExperimentalTaskStore { } - - /** - * Identifies a set of snapshot fields to be fully hydrated when creating the snapshot. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.PARAMETER, ElementType.METHOD }) - @Qualifier - public @interface HydrateSnapshotFields { } @Inject public SnapshotStoreImpl( BuildInfo buildInfo, Clock clock, @Volatile Storage storage, - @ExperimentalTaskStore boolean useDbSnapshotForTaskStore, - @HydrateSnapshotFields Set<String> hydrateSnapshotFields, - MigrationManager migrationManager, - ThriftBackfill thriftBackfill, - EnumBackfill enumBackfill) { + ThriftBackfill thriftBackfill) { this.buildInfo = requireNonNull(buildInfo); this.clock = requireNonNull(clock); this.storage = requireNonNull(storage); - this.useDbSnapshotForTaskStore = useDbSnapshotForTaskStore; - this.hydrateSnapshotFields = requireNonNull(hydrateSnapshotFields); - this.migrationManager = requireNonNull(migrationManager); this.thriftBackfill = requireNonNull(thriftBackfill); - this.enumBackfill = requireNonNull(enumBackfill); } - @Timed("snapshot_create") - @Override - public Snapshot createSnapshot() { + private Snapshot createSnapshot(Storage anyStorage) { // It's important to perform snapshot creation in a write lock to ensure all upstream callers // are correctly synchronized (e.g. during backup creation). - return storage.write(storeProvider -> { + return anyStorage.write(storeProvider -> { Snapshot snapshot = new Snapshot(); // Capture timestamp to signify the beginning of a snapshot operation, apply after in case @@ -505,6 +405,12 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> { }); } + @Timed("snapshot_create") + @Override + public Snapshot createSnapshot() { + return createSnapshot(storage); + } + @Timed("snapshot_apply") @Override public void applySnapshot(final Snapshot snapshot) { http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java b/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java index 170f9ff..a5b58e8 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java @@ -358,12 +358,6 @@ class WriteAheadStorage implements } @Override - public <T> T getUnsafeStoreAccess() { - throw new UnsupportedOperationException( - "Unsupported since casual storage users should never be doing this."); - } - - @Override public Optional<String> fetchFrameworkId() { return this.schedulerStore.fetchFrameworkId(); } http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java b/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java deleted file mode 100644 index 24296b6..0000000 --- a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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.scheduler.storage.mem; - -import javax.inject.Singleton; - -import com.google.inject.Key; -import com.google.inject.PrivateModule; -import com.google.inject.TypeLiteral; - -import org.apache.aurora.common.inject.Bindings.KeyFactory; -import org.apache.aurora.common.quantity.Amount; -import org.apache.aurora.common.quantity.Time; -import org.apache.aurora.scheduler.storage.CronJobStore; -import org.apache.aurora.scheduler.storage.TaskStore; -import org.apache.aurora.scheduler.storage.db.DbModule; -import org.apache.aurora.scheduler.storage.db.DbModule.Options; -import org.apache.aurora.scheduler.storage.mem.MemTaskStore.SlowQueryThreshold; - -import static java.util.Objects.requireNonNull; - -/** - * Binding module for in-memory stores. - * <p> - * NOTE: These stores are being phased out in favor of database-backed stores. - */ -public final class InMemStoresModule extends PrivateModule { - - private final Options options; - private final KeyFactory keyFactory; - - public InMemStoresModule(DbModule.Options options, KeyFactory keyFactory) { - this.options = requireNonNull(options); - this.keyFactory = requireNonNull(keyFactory); - } - - private <T> void bindStore(Class<T> binding, Class<? extends T> impl) { - bind(binding).to(impl); - bind(impl).in(Singleton.class); - Key<T> key = keyFactory.create(binding); - bind(key).to(impl); - expose(key); - } - - @Override - protected void configure() { - bind(new TypeLiteral<Amount<Long, Time>>() { }).annotatedWith(SlowQueryThreshold.class) - .toInstance(options.slowQueryLogThreshold); - bindStore(TaskStore.Mutable.class, MemTaskStore.class); - expose(TaskStore.Mutable.class); - bindStore(CronJobStore.Mutable.class, MemCronJobStore.class); - expose(CronJobStore.Mutable.class); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java new file mode 100644 index 0000000..483af19 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java @@ -0,0 +1,82 @@ +/** + * 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.scheduler.storage.mem; + +import java.util.Map; +import java.util.Set; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; + +import org.apache.aurora.gen.Attribute; +import org.apache.aurora.gen.HostAttributes; +import org.apache.aurora.gen.MaintenanceMode; +import org.apache.aurora.scheduler.storage.AttributeStore; +import org.apache.aurora.scheduler.storage.entities.IHostAttributes; + +/** + * An in-memory attribute store. + */ +class MemAttributeStore implements AttributeStore.Mutable { + private final Map<String, IHostAttributes> hostAttributes = Maps.newConcurrentMap(); + + @Override + public void deleteHostAttributes() { + hostAttributes.clear(); + } + + @Override + public boolean saveHostAttributes(IHostAttributes attributes) { + Preconditions.checkArgument( + FluentIterable.from(attributes.getAttributes()).allMatch(a -> !a.getValues().isEmpty())); + Preconditions.checkArgument(attributes.isSetMode()); + + IHostAttributes previous = hostAttributes.put( + attributes.getHost(), + merge(attributes, Optional.fromNullable(hostAttributes.get(attributes.getHost())))); + return attributes.equals(previous); + } + + private IHostAttributes merge(IHostAttributes newAttributes, Optional<IHostAttributes> previous) { + HostAttributes attributes = newAttributes.newBuilder(); + if (!attributes.isSetMode()) { + // If the newly-saved value does not explicitly set the mode, use the previous value + // or the default. + MaintenanceMode mode; + if (previous.isPresent() && previous.get().isSetMode()) { + mode = previous.get().getMode(); + } else { + mode = MaintenanceMode.NONE; + } + attributes.setMode(mode); + } + if (!attributes.isSetAttributes()) { + attributes.setAttributes(ImmutableSet.<Attribute>of()); + } + return IHostAttributes.build(attributes); + } + + @Override + public Optional<IHostAttributes> getHostAttributes(String host) { + return Optional.fromNullable(hostAttributes.get(host)); + } + + @Override + public Set<IHostAttributes> getHostAttributes() { + return ImmutableSet.copyOf(hostAttributes.values()); + } +}
