Replication/cluster locality

This spec describes the work required to add locality
to replication sets and clusters.

APIImpact

References: blueprint replication-cluster-locality
Change-Id: I061f086f90899c6287fcdac3c88523d62f4e4b30
This commit is contained in:
Peter Stachowski 2016-03-29 21:37:19 +00:00
parent c9df7a1e46
commit b2cbd74b4a

View File

@ -0,0 +1,396 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
Sections of this template were taken directly from the Nova spec
template at:
https://github.com/openstack/nova-specs/blob/master/specs/template.rst
..
This template should be in ReSTructured text. The filename in the git
repository should match the launchpad URL, for example a URL of
https://blueprints.launchpad.net/trove/+spec/awesome-thing should be named
awesome-thing.rst.
Please do not delete any of the sections in this template. If you
have nothing to say for a whole section, just write: None
Note: This comment may be removed if desired, however the license notice
above should remain.
============================
Replication/Cluster Locality
============================
.. If section numbers are desired, unindent this
.. sectnum::
.. If a TOC is desired, unindent this
.. contents::
Nova has the ability to control whether new instances are created on the same
hypervisor (affinity) or on different hypervisors (anti-affinity). This
behaviour is useful when setting up replication networks or clusters, so it is
proposed to add support for it into Trove.
Launchpad Blueprint:
https://blueprints.launchpad.net/trove/+spec/replication-cluster-locality
Problem Description
===================
At times it is desirable to control where replicas in a replication set are
created. In the case of read slaves, there may be a requirement to ensure that
all replicas are on the same hypervisor, whereas for high availability it may
be desired that all replicas are created on different hypervisors.
By the same token, clusters would benefit from having instances on different
hypervisors.
Replication/cluster locality seeks to address this issue. (Granted,
anti-affinity seems more relevant - and desirable - however the two go
hand-in-hand as will be seen in the next section.)
Proposed Change
===============
Nova has the capability of placing new instances on the same hypervisor, or on
different ones. Within Nova this is handled through the use of 'server
groups.' [1]_ Using this feature of Nova will require sending a server_group
'hint' to the nova_client.servers.create call. This functionality will be used
'under the covers' similar to how secgroups are managed now.
Trove will perform the following actions to accomplish this:
* The create_instance method in the Task Manager will be changed to include
a 'locality' argument.
.. code-block:: python
def create_instance(self, context, instance_id, name, flavor,
image_id, databases, users, datastore_manager,
packages, volume_size, backup_id, availability_zone,
root_password, nics, overrides, slave_of_id,
cluster_config, volume_type, locality):
* The create method in cluster/models.py will likewise be modified to include
a 'locality' argument.
.. code-block:: python
@classmethod
def create(cls, context, name, datastore, datastore_version,
instances, extended_properties, locality):
* The locality argument will be used to create a server group with the
corresponding policy (affinity or anti-affinity).
* The server group details will be converted to a Nova 'hint.'
* This hint will be passed into the Nova client in the create call in
taskmanager/models.py.
Note: If affinity is chosen and the hypervisor does not have enough resources,
then some of the instances will fail to create. The same goes for choosing
anti-affinity and there are not enough available hypervisors. There may be
other cases where Nova is unable to create the instance (affinity chosen, but
different AZ's); in these cases the new instance will likely fail to spawn as
well.
The Trove show and cluster-show commands will also be modified to show the
'locality' value (i.e. the server_group policy), if it exists.
Configuration
-------------
No changes
Database
--------
No changes. The server_group id will be obtained from Nova when it's needed.
Public API
----------
An attribute 'locality' will be added to the data payload sent during a
'create' command. The request/response will look like:
Request::
POST v1/{tenant_id}/instances
{
"instance":
{
"volume":
{
"type": null,
"size": 1
},
"flavorRef": 7,
"name": "myinst",
"replica_count": 2,
"locality": "affinity"
}
}
Response::
{
"instance":
{
"status": "BUILD",
"updated": "2015-12-13T12:36:59",
"name": "myinst",
"links":
[
{
"href": "https://10.240.64.151:8779/v1.0/<tenant>/instances/<id>",
"rel": "self"
},
{
"href": "https://10.240.64.151:8779/instances/<id>",
"rel": "bookmark"
}
],
"created": "2015-12-13T12:36:59",
"id": "<id>",
"volume":
{
"size": 1
},
"flavor":
{
"id": "7",
"links":
[
{
"href": "https://10.240.64.151:8779/v1.0/<tenant>/flavors/7",
"rel": "self"
},
{
"href": "https://10.240.64.151:8779/flavors/7",
"rel": "bookmark"
}
]
},
"datastore":
{
"version": "5.6",
"type": "mysql"
},
"locality": "affinity"
}
}
The 'show' and 'cluster-show' commands will also now return an attribute
'locality' that will look like the one returned from their respective create
commands.
Public API Security
-------------------
No impact
Python API
----------
A new argument 'locality' will be added to the Trove create command (this will
be passed through to the Nova client as a hint by the Task Manager, after
creating the corresponding server group). The new Python API signature will
be:
.. code-block:: python
def create(self, name, flavor_id, volume=None, databases=None, users=None,
restorePoint=None, availability_zone=None, datastore=None,
datastore_version=None, nics=None, configuration=None,
replica_of=None, slave_of=None, replica_count=None,
locality=None):
The Python API signature for cluster-create will be:
.. code-block:: python
def create(self, name, datastore, datastore_version, instances=None,
locality=None):
CLI (python-troveclient)
------------------------
The create command will now accept a --locality flag that can be one of two
values: affinity and anti-affinity. The command would look like:
.. code-block:: bash
trove create my_instance 7 --size 1 --locality affinity
For clusters it will be:
.. code-block:: bash
trove cluster-create my_cluster mysql 5.6 --locality affinity \
--instance flavor=10,volume=1 \
--instance flavor=10,volume=1 \
--instance flavor=10,volume=1 \
Replicas can then be created in the usual fashion, with all following the
locality setting of the master node. If adding replicas to an existing set,
an exception will be thrown if --locality is specified, as this flag
cannot be changed once it has been associated with an instance (this is a Nova
restriction in that servers can't be added or removed from a group manually).
For example, the following command would fail:
.. code-block:: bash
trove create my_replica 7 --size 1 --locality affinity --replica_of <id>
When growing a cluster, the same locality will be applied to any new instances
created. Because of this, the locality flag will not be available for
cluster-grow.
The show and cluster-show commands will also display the locality value. For
example:
.. code-block:: bash
> trove show my_instance
+-------------------+-------------------------+
| Property | Value |
+-------------------+-------------------------+
| created | 2015-12-13T12:36:59 |
| datastore | mysql |
| datastore_version | 5.6 |
| flavor | 7 |
| id | <id> |
| ip | 10.64.151.6 |
| name | my_instance |
| status | ACTIVE |
| updated | 2015-12-13T12:37:03 |
| volume | 1 |
| volume_used | 0.1 |
| locality | affinity |
+-------------------+-------------------------+
If locality is not specified, then no hint will be sent to Nova and it will
follow its default algorithm for deciding what hypervisor to use.
For operator assistance in debugging issues the server group id could be
displayed through a management call, but will be kept hidden from end users
(just as the Nova instance id is not displayed).
Internal API
------------
The Task Manager is responsible for creating the replication and cluster
instances, so it will need to be aware of the locality flag. The relevant
methods will be changed to include this, as described above.
Once the flag is converted to a server group, a 'hint' will be created to pass
to the Nova client. The converted hint data will be equivalent to the
corresponding ReST API values:
.. code-block:: python
"os:scheduler_hints":
{
"group": "<id>"
}
Guest Agent
-----------
Since the server group must be created before the Nova instance is created,
there are no anticipated Guest Agent changes.
Alternatives
------------
The server_group id could be stored in the Trove database. The trade-off to
any speed improvements (from not having to request the information from Nova)
would be that Trove would have to manage this field properly. If it got out of
sync then Trove wouldn't function as expected.
Dashboard Impact (UX)
=====================
For each of the instance create and cluster create screens, a drop-down
for locality will need to be added. This drop-down will have 'None',
'affinity', and 'anti-affinity' in it. The value chosen will need
to be passed down into the respective create calls. The show commands
will need to be enhanced as well to recognize the new 'locality' element.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
peterstac
Milestones
----------
Target Milestone for completion:
Newton-1
Work Items
----------
The work will be undertaken with the following tasks:
* Client (Python and CLI) changes for replication
* Server (API and TaskManager) changes for replication
* Client (Python and CLI) changes for clustering
* Server (API and TaskManager) changes for clustering
Upgrade Implications
====================
Since this change is completely backwards compatible, no upgrade issues are
expected.
Dependencies
============
None
Testing
=======
The replication scenario test will be modified to use --locality=affinity and
the results verified (i.e. that the Trove 'show' command returns the right
value for the 'locality' attribute). A negative test with anti-affinity will
also be created (since devstack runs on one hypervisor, this test should always
fail to create replicas). As far as it is feasible with respect to resources
consumed, this same pattern will be used in the cluster scenario tests.
Documentation Impact
====================
This is a net-new feature, and as such will require documentation.
References
==========
.. [1] Output from running 'nova help server-group-create'
Appendix
========
None