实现 Percona 集群配置

为了继续 Trove HA 的故事,需要数据库实例的高可用性,以便在 Trove 中运行生产工作负载时让用户安心。除了复制之外,集群还允许从集群中的任何节点访问数据,从而使部署具有高可用性。它增强了系统正常运行时间,防止数据丢失,并使架构更具可扩展性,以适应未来的增长。Trove 集群对于 Percona 数据存储将基于 Percona XtraDB 集群,这是一种基于同步复制的真正的多主集群。

此更改将重点关注 Peronca 集群的创建、列出、显示和删除。集群的扩展和缩减将在单独的蓝图处理。

https://blueprints.launchpad.net/trove/+spec/support-pxc-56

问题描述

Percona 数据存储不支持集群。添加集群实现将允许用户创建可读写扩展且高度可用的部署。

提议的变更

Percona 集群将利用 Trove 中当前存在的基集群实现,通过创建可插拔和可配置的策略来实现。

要求

  • 集群中的节点数量不得少于三个。

  • 初始集群创建将从 3 个或更多节点开始。

  • 集群将返回其所有节点的 IP 地址。这是为了使集群可用于多写和多读。

  • 每个实例的名称将自动生成,格式为 <cluster_name>-<instance_num>。

  • 集群中的节点应具有相同大小的卷,但对于规格(flavors)则不必相同。

  • 集群应允许实例/集群成员在卷和规格方面进行调整。如果用户调整实例的卷或规格,将不会进行验证。

以下内容将被更改

  • 将在 common/strategies/cluster/experimental/mysql/xtradbcluster 中添加一个 percona-cluster 实现

  • 任务管理器策略,用于处理 Percona 的集群配置。

  • Guestagent 策略,用于处理集群配置、配置和执行。

  • 单元测试和集成测试。

配置

将添加一个新的数据存储配置部分。此初始实现将不会添加任何 Percona-Cluster 特定的配置选项。

Trove 集成

Redstack 脚本将为 percona-cluster 创建一个数据存储配置,以打开端口 3306、4444、4567 和 4568。

将添加元素以支持“redstack kick-start percona-cluster-5.6”。

数据库

此实现将利用现有的集群数据库模式。

公共 API

创建/删除集群的 API 请求将保持不变。但是,响应会有一些细微的差异。Percona 集群将返回其所有节点的 IP 地址。这将用于希望扩展读/写操作的用户。

创建集群

请求

POST /v1.0/<tenant_id>/clusters
{
  "cluster": {
    "name": "products",
    "datastore": {
      "type": "percona",
      "version": "5.5"
    },
    "instances": [
      {
        "flavorRef": "2",
        "volume": {
          "size": 100
        },
      },
      {
        "flavorRef": "2",
        "volume": {
          "size": 100
        },
      },
      {
        "flavorRef": "2",
        "volume": {
          "size": 100
        },
      }
    ],
  }
}

响应

{
  "cluster": {
    "id": "dfbbd9ca-b5e1-4028-adb7-f78643e17998",
    "task": {
      "id": 2,
      "name": "BUILDING",
      "description": "Building the initial cluster."
    },
    "name": "products",
    "created": "2014-04-25T20:19:23",
    "updated": "2014-04-25T20:19:23",
    "links": [{...}],
    "datastore": {
      "type": "percona",
      "version": "5.5"
    },
    "instances": [
      {
        "id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
        "status": "BUILD",
        "flavor": {
          "id": "2",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
      },
      {
        "id": "965ef811-7c1d-47fc-89f2-a89dfdd23ef2",
        "status": "BUILD",
        "flavor": {
          "id": "2",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
      },
      {
        "id": "3642f41c-e8ad-4164-a089-3891bf7f2d2b",
        "status": "BUILD",
        "flavor": {
          "id": "2",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
      }
    ],
  }
}

显示集群

请求

GET /v1.0/<tenant_id>/clusters/dfbbd9ca-b5e1-4028-adb7-f78643e17998

响应

{
  "cluster": {
    "id": "dfbbd9ca-b5e1-4028-adb7-f78643e17998",
    "task": {
      "id": 1,
      "name": "NONE",
      "description": "No tasks for the cluster."
    },
    "name": "products",
    "created": "2014-04-25T20:19:23",
    "updated": "2014-04-25T20:19:23",
    "links": [{...}],
    "datastore": {
      "type": "percona",
      "version": "5.5"
    },
    "instances": [
      {
        "id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
        "status": "ACTIVE",
        "flavor": {
          "id": "7",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
        "ip": "10.0.0.1"
      }
      {
        "id": "965ef811-7c1d-47fc-89f2-a89dfdd23ef2",
        "status": "ACTIVE",
        "flavor": {
          "id": "7",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
        "ip": "10.0.0.2"
      },
      {
        "id": "3642f41c-e8ad-4164-a089-3891bf7f2d2b",
        "status": "BUILD",
        "flavor": {
          "id": "7",
          "links": [{...}]
        },
        "volume": {
          "size": 100
        },
        "ip": "10.0.0.3"
      }
    ],
  }
}

显示实例

请求

GET /v1.0/<tenant_id>/clusters/dfbbd9ca-b5e1-4028-adb7-f78643e17998/instances/416b0b16-ba55-4302-bbd3-ff566032e1c1

响应

{
  "instance": {
    "status": "ACTIVE",
    "id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
    "cluster_id": "dfbbd9ca-b5e1-4028-adb7-f78643e17998",
    "name": "products-1",
    "created": "2014-04-25T20:19:23",
    "updated": "2014-04-25T20:19:23",
    "links": [{...}],
    "datastore": {
      "type": "percona",
      "version": "5.5"
    },
    "ip": ["10.0.0.1"],
    "flavor": {
      "id": "7",
      "links": [{...}],
    },
    "volume": {
      "size": 100,
      "used": 0.17
    },
  }
}

列出集群

请求

GET /v1.0/<tenant_id>/clusters

响应

{
  "clusters": [
    {
      "id": "dfbbd9ca-b5e1-4028-adb7-f78643e17998",
      "task": {
        "id": 1,
        "name": "NONE",
        "description": "No tasks for the cluster."
      },
      "name": "products",
      "created": "2014-04-25T20:19:23",
      "updated": "2014-04-25T20:19:23",
      "links": [{...}],
      "ip": ["10.0.0.1", "10.0.0.2", "10.0.0.3"],
      "datastore": {
        "type": "percona",
        "version": "5.5"
      },
      "instances": [
        {
          "id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
          "status": "ACTIVE",
          "flavor": {
            "id": "7",
            "links": [{...}]
          },
          "volume": {
            "size": 100
          },
          "ip": "10.0.0.1",
        }
        {
          "id": "965ef811-7c1d-47fc-89f2-a89dfdd23ef2",
          "status": "ACTIVE",
          "flavor": {
            "id": "7",
            "links": [{...}]
          },
          "volume": {
            "size": 100
          },
          "ip": "10.0.0.2",
        },
        {
          "id": "3642f41c-e8ad-4164-a089-3891bf7f2d2b",
          "status": "ACTIVE",
          "flavor": {
            "id": "7",
            "links": [{...}]
          },
          "volume": {
            "size": 100
          },
          "ip": "10.0.0.3",
        }
      ]
    },
    ...
  ]
}

删除集群

请求

DELETE /v1.0/<tenant_id>/clusters/dfbbd9ca-b5e1-4028-adb7-f78643e17998

响应

HTTP 202 (Empty Body)

公共 API 安全

内部 API

内部 API 尚未更改。

Guest Agent

Guest agent 的 API 没有更改。此功能只是添加了一个新的策略来支持不同类型的集群。

CLI (python-troveclient)

以下说明了集群 CLI

创建集群

$ trove help cluster-create

usage: trove cluster-create <name> <datastore> <datastore_version>
                            [--instance <instance>]

Creates a new cluster.

Positional arguments:
  <name>                Name of the cluster.
  <datastore>           A datastore name or UUID.
  <datastore_version>   A datastore version name or UUID.

Optional arguments:

  --instance <flavor_id=flavor_id,volume=volume,parameters=<key=value>>
                        Create an instance for the cluster. Specify
                        multiple times to create multiple instances.

请求

$ trove cluster-create products percona "5.5" \
  --instance flavor_id=7,volume=2 \
  --instance flavor_id=7,volume=2 \
  --instance flavor_id=7,volume=2

响应

+-------------------+--------------------------------------+
| Property          | Value                                |
+-------------------+--------------------------------------+
| created           | 2014-08-16T01:46:51                  |
| datastore         | percona                              |
| datastore_version | 5.5                                  |
| id                | aa6ef0f5-dbef-48cd-8952-573ad881e717 |
| name              | products                             |
| task_description  | Building the initial cluster.        |
| task_name         | BUILDING                             |
| updated           | 2014-08-16T01:46:51                  |
+-------------------+--------------------------------------+

cluster-create 命令将创建一个功能等效的 Trove 实例集群。Trove 将选择一个实例来启动,并使用 –wsrep-new-cluster 选项,然后按顺序启动其余实例。当所有实例都已启动并且数据库可用时,集群将被标记为 ACTIVE。

显示集群

$ trove help cluster-show

usage: trove cluster-show <cluster>

Shows details of a cluster.

Positional arguments:
  <cluster>  ID or name of the cluster.

请求

$ trove cluster-show aa6ef0f5-dbef-48cd-8952-573ad881e717

响应

+-------------------+--------------------------------------+
| Property          | Value                                |
+-------------------+--------------------------------------+
| created           | 2014-08-16T01:46:51                  |
| datastore         | percona                              |
| datastore_version | 5.5                                  |
| id                | aa6ef0f5-dbef-48cd-8952-573ad881e717 |
| ip                | 10.0.0.2, 10.0.0.1, 10.0.0.3         |
| name              | products                             |
| task_description  | No tasks for the cluster.            |
| task_name         | NONE                                 |
| updated           | 2014-08-16T01:59:33                  |
+-------------------+--------------------------------------+

显示集群实例

$ trove help cluster-instances

usage: trove cluster-instances <cluster>

Lists all instances of a cluster.

Positional arguments:
  <cluster>  ID or name of the cluster.

请求

$ trove cluster-instances aa6ef0f5-dbef-48cd-8952-573ad881e717

响应

+-------------------------------------+----------------+-----------+------+
| ID                                  | Name           | Flavor ID | Size |
+-------------------------------------+----------------+-----------+------+
| 45532fc4-661c-4030-8ca4-18f02a2b337 | products-1     | 7         |    2 |
| 7458a98d-6f89-4dfd-bb61-5cf1d65c121 | products-2     | 8         |    2 |
| 1557208f-5c23-4537-a9f2-52a9db38d3a | products-3     | 7         |    2 |
+-------------------------------------+----------------+-----------+------+

列出集群

$ trove help cluster-list

usage: trove cluster-list [--limit <limit>] [--marker <ID>]

Lists all the clusters.

Optional arguments:
  --limit <limit>  Limit the number of results displayed.
  --marker <ID>    Begin displaying the results for IDs greater than the
                   specified marker. When used with --limit, set this to
                   the last ID displayed in the previous run.

请求

$ trove cluster-list

响应

+--------+----------+-----------+-----------+----------+-----------+
| ID     | Name     | Datastore | DsVersion | IP       | Task Name |
+--------+----------+-----------+-----------+----------+-----------+
| uuid-1 | products | percona   | 5.5       | ip1      | NONE      |
| uuid-2 | items    | percona   | 5.5       | ip2, ip3 | BUILDING  |
+--------+----------+-----------+-----------+----------+-----------+

删除集群

$ trove help cluster-delete

usage: trove cluster-delete <cluster>

Deletes a cluster.

Positional arguments:
  <cluster>  ID of the cluster.

请求

$ trove cluster-delete aa6ef0f5-dbef-48cd-8952-573ad881e717

响应

(None)

复制影响

由于将副本添加到集群的范围,这将作为此蓝图的一部分被禁用,并作为单独的蓝图添加。4

Python API

???

备选方案

尚未定义。

升级影响

为了支持 MySQL 集群,需要在 guest 实例上安装与默认安装不同的软件包。在升级路径中,可以通过以下 2 种方式缓解此问题:

  1. 更新数据存储版本上安装的软件包。

  2. 构建一个新镜像,将新软件包安装到 guest 镜像中。

实现

负责人

名称

Launchpad ID

IRC

Email

Steve Leon

steve-leon

esmute

kokhang@gmail.com

Morgan Jones

6-morgan

vgnbkr

morgan@tesora.com

Craig Vyvial

cp16net

cp16net

cp16net@gmail.com

里程碑

Liberty-3

工作项

  • Trove 集成,以添加 percona-xtradb-cluster-server 软件包

  • API 策略实现

  • 任务管理器策略实现

  • Guestagent 策略实现

  • 单元和集成测试

依赖项

测试

将有单元测试来测试策略中的每个组件。将有集成测试,将测试端到端集群功能

文档影响

由于 XtraDB 集群的性质,响应 API 的外观会有所不同。例如,视图将包含所有实例的 IP 地址。

参考资料

API 策略,用于处理 Percona 的集群请求。除了现有的 API 之外,还将有新的 API 来扩展/缩减集群,这些 API 在另一个蓝图中处理。(bp/cluster-scaling 1

Trove 不会监控集群实例的状态。如果集群中的实例与主实例断开连接,用户需要检测到这种情况并采取纠正措施。如果实例无法以可以进行增量状态传输 (IST) 的状态重新连接到集群,建议删除该实例并向集群添加一个新节点。(将来,用户可以通过缩减操作从集群中删除实例,并通过扩展操作向集群添加新实例。)

如果 nova compute 重新启动,节点将自动重新启动,并且只要节点能够确定可以正确恢复 PRIMARY 组件,集群将自动恢复。如果无法恢复 PRIMARY 组件,则需要操作员干预才能手动重新启动集群。

其他集群相关蓝图的列表。这些蓝图可能会导致与更改冲突。

1

bp/cluster-scaling:https://blueprints.launchpad.net/trove/+spec/cluster-scaling

4

percona-xtradb-with-replica:https://blueprints.launchpad.net/trove/+spec/percona-add-replica-of-cluster

bp/mysql-manager-refactor

https://blueprints.launchpad.net/trove/+spec/mysql-manager-refactor

bp/cluster-user-management

https://blueprints.launchpad.net/trove/+spec/cluster-user-management