复制/集群位置¶
Nova 具有控制新实例是在同一 hypervisor(亲和性)还是不同 hypervisor(反亲和性)上创建的能力。这种行为在设置复制网络或集群时很有用,因此建议将其支持添加到 Trove 中。
Launchpad Blueprint: https://blueprints.launchpad.net/trove/+spec/replication-cluster-locality
问题描述¶
有时,控制复制集中副本的位置是期望的。对于只读从库,可能需要确保所有副本都在同一 hypervisor 上,而对于高可用性,可能希望所有副本都在不同的 hypervisor 上创建。
同样,集群也会受益于在不同 hypervisor 上拥有实例。
复制/集群位置旨在解决此问题。(诚然,反亲和性似乎更相关且更可取,但两者是相辅相成的,如下一节所示。)
提议的变更¶
Nova 具有将新实例放置在同一 hypervisor 或不同 hypervisor 上的能力。在 Nova 中,这是通过使用“服务器组”处理的。1 使用 Nova 的此功能需要将 server_group “hint” 发送到 nova_client.servers.create 调用。此功能将在“幕后”使用,类似于当前管理 secgroups 的方式。
Trove 将执行以下操作来实现这一点
任务管理器中的 create_instance 方法将被更改为包含“locality”参数。
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):
cluster/models.py 中的 create 方法也将被修改为包含“locality”参数。
@classmethod
def create(cls, context, name, datastore, datastore_version,
instances, extended_properties, locality):
locality 参数将用于创建具有相应策略(亲和性或反亲和性)的服务器组。
服务器组详细信息将被转换为 Nova “hint”。
此 hint 将传递到 taskmanager/models.py 中的 create 调用中的 Nova 客户端。
注意:如果选择亲和性而 hypervisor 没有足够的资源,则某些实例将无法创建。如果选择反亲和性且没有足够的可用 hypervisor,则情况也是如此。在 Nova 无法创建实例的其他情况下(选择亲和性,但不同的 AZ),新实例也可能无法启动。
Trove show 和 cluster-show 命令也将被修改为显示“locality”值(即服务器组策略),如果存在的话。
配置¶
无更改
数据库¶
无更改。服务器组 ID 将在需要时从 Nova 获取。
公共 API¶
一个“locality”属性将被添加到“create”命令期间发送的数据有效负载中。请求/响应将如下所示
请求
POST v1/{tenant_id}/instances
{
"instance":
{
"volume":
{
"type": null,
"size": 1
},
"flavorRef": 7,
"name": "myinst",
"replica_count": 2,
"locality": "affinity"
}
}
响应
{
"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"
}
}
“show”和“cluster-show”命令现在也将返回一个“locality”属性,该属性将类似于其各自的 create 命令返回的属性。
公共 API 安全¶
无影响
Python API¶
将向 Trove create 命令添加一个新的参数“locality”(这将通过任务管理器传递到 Nova 客户端,在创建相应的服务器组之后)。新的 Python API 签名将是
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):
cluster-create 的 Python API 签名将是
def create(self, name, datastore, datastore_version, instances=None,
locality=None):
CLI (python-troveclient)¶
create 命令现在将接受一个 –locality 标志,该标志可以是以下两个值之一:affinity 和 anti-affinity。命令将如下所示
trove create my_instance 7 --size 1 --locality affinity
对于集群,将是
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 \
然后可以以通常的方式创建副本,所有副本都遵循主节点的 locality 设置。如果将副本添加到现有集合,如果指定了 –locality,则会抛出异常,因为此标志一旦与实例关联就无法更改(这是 Nova 的限制,即服务器无法手动添加到或从组中删除)。例如,以下命令将失败
trove create my_replica 7 --size 1 --locality affinity --replica_of <id>
在扩展集群时,将对任何新创建的实例应用相同的 locality。因此,locality 标志将不可用于 cluster-grow。
show 和 cluster-show 命令还将显示 locality 值。例如
> 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 |
+-------------------+-------------------------+
如果未指定 locality,则不会向 Nova 发送任何 hint,它将遵循其默认算法来决定使用哪个 hypervisor。
为了帮助操作员调试问题,服务器组 ID 可以通过管理调用显示,但将对最终用户隐藏(就像 Nova 实例 ID 不会显示一样)。
内部 API¶
任务管理器负责创建复制和集群实例,因此需要了解 locality 标志。相关方法将被更改为包含此标志,如上所述。
一旦标志被转换为服务器组,将创建一个“hint”传递给 Nova 客户端。转换后的 hint 数据将等效于相应的 ReST API 值
"os:scheduler_hints":
{
"group": "<id>"
}
Guest Agent¶
由于服务器组必须在创建 Nova 实例之前创建,因此预计不会有 Guest Agent 更改。
备选方案¶
服务器组 ID 可以存储在 Trove 数据库中。对任何速度改进的权衡(不必从 Nova 请求信息)将是 Trove 将必须正确管理此字段。如果不同步,Trove 将无法按预期工作。
Dashboard 影响 (UX)¶
对于每个实例创建和集群创建屏幕,都需要添加一个用于 locality 的下拉菜单。此下拉菜单将包含“None”、“affinity”和“anti-affinity”。选择的值需要传递到各自的 create 调用中。show 命令也需要进行增强,以识别新的“locality”元素。
实现¶
负责人¶
- 主要负责人
peterstac
里程碑¶
- 完成目标里程碑
Newton-1
工作项¶
将使用以下任务完成这项工作
复制的客户端(Python 和 CLI)更改
复制的服务器(API 和 TaskManager)更改
集群的客户端(Python 和 CLI)更改
集群的服务器(API 和 TaskManager)更改
升级影响¶
由于此更改完全向后兼容,因此预计不会出现升级问题。
依赖项¶
无
测试¶
复制场景测试将被修改为使用 –locality=affinity,并验证结果(即 Trove “show”命令返回“locality”属性的正确值)。还将创建一个反亲和性的负面测试(由于 devstack 在一个 hypervisor 上运行,此测试应始终无法创建副本)。在资源消耗方面可行的情况下,将对集群场景测试使用相同的模式。
文档影响¶
这是一个全新的功能,因此需要文档。
附录¶
无