复制/集群位置

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 上运行,此测试应始终无法创建副本)。在资源消耗方面可行的情况下,将对集群场景测试使用相同的模式。

文档影响

这是一个全新的功能,因此需要文档。

参考资料

1

运行“nova help server-group-create”的输出

附录