Cells: Add the main code.

This introduces *EXPERIMENTAL* compute cells functionality as a way to
scale nova in a more distributed fashion without having to use complicated
technologies like DB and message queue clustering.

Cells are configured as a tree and the top level cell should contain
nova-api without any nova-computes while child cells contain everything
except nova-api.  One can think of a cell as a normal nova deployment in
that each cell has its own DB server and message queue broker.

The top level cell keeps a subset of data about ALL instances in all
cells in its DB.  Child cells send messages to the top level cell when
instances change state.  Data in 1 child cell is not shared with another
child cell.

A new service, nova-cells, is introduced that handles communication
between cells and picking of a cell for new instances.  This service is
required for every cell.  Communication between cells is pluggable with
the only option currently implemented being communnication via RPC.

Cells scheduling is separate from host scheduling.  nova-cells first picks
a cell (currently randomly -- future patches add filtering/weighing
functionality and decisions can be based on broadcasts of
capacity/capabilities).  Once a cell has been selected and the new build
request has reached its nova-cells service, it'll be sent over to the host
scheduler in that cell and the build proceeds as it does without cells.

New config options are introduced for enabling and configuring the cells
code.  Cells is disabled by default.  All of the config options below go
under a '[cells]' section in nova.conf.  These are the options that one
may want to tweak:

enable -- Turn on cells code (default is False)
name -- Name of the current cell.
capabilities -- List of arbitrary key=value pairs defining capabilities
                of the current cell.  These are sent to parent cells,
                but aren't used in scheduling until later filter/weight
                support is added.
call_timeout -- How long to wait for replies from a calls between cells

When using cells, the compute API class must be changed in the API cell,
so that requests can be proxied via nova-cells down to the correct cell
properly.  Thus, config requirements for API cell:

--
[DEFAULT]
compute_api_class=nova.compute.cells_api.ComputeCellsAPI.
[cells]
enable=True
name=api-cell
--

Config requirements for child cell:

--
[cells]
enable=True
name=child-cell1
--

Another requirement is populating the 'cells' DB table in each cell.
Each cell needs to know about its parent and children and how to
communicate with them (message broker location, credentials, etc).

Implements blueprint nova-compute-cells

DocImpact

Change-Id: I1b52788ea9d7753365d175abf39bdbc22ba822fe
This commit is contained in:
Chris Behrens 2012-04-13 05:54:48 +00:00
parent 795f3f9952
commit 188854a79f
3 changed files with 82 additions and 0 deletions

53
bin/nova-cells Executable file
View File

@ -0,0 +1,53 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (c) 2012 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.
"""Starter script for Nova Cells Service."""
import eventlet
eventlet.monkey_patch()
import os
import sys
# If ../nova/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
from nova import config
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova import service
from nova import utils
CONF = cfg.CONF
CONF.import_opt('topic', 'nova.cells.opts', group='cells')
CONF.import_opt('manager', 'nova.cells.opts', group='cells')
if __name__ == '__main__':
config.parse_args(sys.argv)
logging.setup('nova')
utils.monkey_patch()
server = service.Service.create(binary='nova-cells',
topic=CONF.cells.topic,
manager=CONF.cells.manager)
service.serve(server)
service.wait()

View File

@ -769,6 +769,34 @@ class CellNotFound(NotFound):
message = _("Cell %(cell_id)s could not be found.")
class CellRoutingInconsistency(NovaException):
message = _("Inconsistency in cell routing: %(reason)s")
class CellServiceAPIMethodNotFound(NotFound):
message = _("Service API method not found: %(detail)s")
class CellTimeout(NotFound):
message = _("Timeout waiting for response from cell")
class CellMaxHopCountReached(NovaException):
message = _("Cell message has reached maximum hop count: %(hop_count)s")
class NoCellsAvailable(NovaException):
message = _("No cells available matching scheduling criteria.")
class CellError(NovaException):
message = _("Exception received during cell processing: %(exc_name)s.")
class InstanceUnknownCell(NotFound):
message = _("Cell is not known for instance %(instance_uuid)s")
class SchedulerHostFilterNotFound(NotFound):
message = _("Scheduler Host Filter %(filter_name)s could not be found.")

View File

@ -50,6 +50,7 @@ setuptools.setup(name='nova',
'bin/nova-api-metadata',
'bin/nova-api-os-compute',
'bin/nova-rpc-zmq-receiver',
'bin/nova-cells',
'bin/nova-cert',
'bin/nova-clear-rabbit-queues',
'bin/nova-compute',