summaryrefslogtreecommitdiff
path: root/nova/scheduler/caching_scheduler.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/scheduler/caching_scheduler.py')
-rw-r--r--nova/scheduler/caching_scheduler.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/nova/scheduler/caching_scheduler.py b/nova/scheduler/caching_scheduler.py
new file mode 100644
index 0000000000..98033e23ac
--- /dev/null
+++ b/nova/scheduler/caching_scheduler.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2014 Rackspace Hosting
+# All Rights Reserved.
+#
+# 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.
+
+from nova.scheduler import filter_scheduler
+
+
+class CachingScheduler(filter_scheduler.FilterScheduler):
+ """Scheduler to test aggressive caching of the host list.
+
+ Please note, this is a very opinionated scheduler. Be sure to
+ review the caveats listed here before selecting this scheduler.
+
+ The aim of this scheduler is to reduce server build times when
+ you have large bursts of server builds, by reducing the time it
+ takes, from the users point of view, to service each schedule
+ request.
+
+ There are two main parts to scheduling a users request:
+ * getting the current state of the system
+ * using filters and weights to pick the best host
+
+ This scheduler tries its best to cache in memory the current
+ state of the system, so we don't need to make the expensive
+ call to get the current state of the system while processing
+ a user's request, we can do that query in a periodic task
+ before the user even issues their request.
+
+ To reduce races, cached info of the chosen host is updated using
+ the existing host state call: consume_from_instance
+
+ Please note, the way this works, each scheduler worker has its own
+ copy of the cache. So if you run multiple schedulers, you will get
+ more retries, because the data stored on any additional scheduler will
+ be more out of date, than if it was fetched from the database.
+
+ In a similar way, if you have a high number of server deletes, the
+ extra capacity from those deletes will not show up until the cache is
+ refreshed.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(CachingScheduler, self).__init__(*args, **kwargs)
+ self.all_host_states = None
+
+ def run_periodic_tasks(self, context):
+ """Called from a periodic tasks in the manager."""
+ elevated = context.elevated()
+ # NOTE(johngarbutt) Fetching the list of hosts before we get
+ # a user request, so no user requests have to wait while we
+ # fetch the list of hosts.
+ self.all_host_states = self._get_up_hosts(elevated)
+
+ def _get_all_host_states(self, context):
+ """Called from the filter scheduler, in a template pattern."""
+ if self.all_host_states is None:
+ # NOTE(johngarbutt) We only get here when we a scheduler request
+ # comes in before the first run of the periodic task.
+ # Rather than raise an error, we fetch the list of hosts.
+ self.all_host_states = self._get_up_hosts(context)
+
+ return self.all_host_states
+
+ def _get_up_hosts(self, context):
+ all_hosts_iterator = self.host_manager.get_all_host_states(context)
+ return list(all_hosts_iterator)