如何在Ubuntu16.04上创建多节点MySQL集群

来自菜鸟教程
跳转至:导航、​搜索

介绍

MySQL 集群是一种提供高可用性和吞吐量的软件技术。 如果您已经熟悉其他集群技术,您会发现与它们类似的 MySQL 集群。 简而言之,有一个或多个管理节点控制数据节点(存储数据的地方)。 与管理节点协商后,客户端(MySQL 客户端、服务器或本机 API)直接连接到数据节点。

您可能想知道 MySQL 复制是如何与 MySQL 集群相关的。 在集群中,没有典型的数据复制,而是数据节点的同步。 为此,必须使用特殊的数据引擎——NDBCluster (NDB)。 将集群视为具有冗余组件的单个逻辑 MySQL 环境。 因此,一个 MySQL 集群可以参与与其他 MySQL 集群的复制。

MySQL 集群在无共享环境中工作得最好。 理想情况下,任何两个组件都不应该共享相同的硬件。 为了简单和演示目的,我们将限制自己只使用三个 Droplet。 将有两个 Droplet 作为数据节点,它们在它们之间同步数据。 第三个 Droplet 将用于集群管理器,同时用于 MySQL 服务器/客户端。 如果你有更多的Droplet,你可以添加更多的数据节点,将集群管理器与MySQL服务器/客户端分开,甚至添加更多的Droplet作为集群管理器和MySQL服务器/客户端。

先决条件

您总共需要三个 Droplet——一个用于 MySQL 集群管理器和 MySQL 服务器/客户端的 Droplet,两个用于冗余 MySQL 数据节点的 Droplet。

相同的 DigitalOcean 数据中心 中,创建以下启用了 私有网络的 Droplet

MySQL 集群在 RAM 中存储了大量信息。 每个 Droplet 至少应具有 1GB 的 RAM。

正如私网教程中提到的,一定要为3个Droplet设置自定义记录。 为了简单和方便,我们将为 /etc/hosts 文件中的每个 Droplet 使用以下自定义记录:

10.XXX.XX.X node1.mysql.cluster 10.YYY.YY.Y node2.mysql.cluster 10.ZZZ.ZZ.Z 管理器.mysql.cluster

请相应地将突出显示的 IP 替换为您的 Droplet 的私有 IP。

除非另有说明,本教程中所有需要 root 权限的命令都应以具有 sudo 权限的非 root 用户身份运行。

第 1 步 — 下载和安装 MySQL 集群

在编写本教程时,MySQL 集群的最新 GPL 版本是 7.4.11。 该产品建立在 MySQL 5.6 之上,它包括:

  • 集群管理软件
  • 数据节点管理软件
  • MySQL 5.6 服务器和客户端二进制文件

您可以从 官方 MySQL 集群下载页面 下载免费的、普遍可用 (GA) MySQL 集群版本。 从此页面中选择同样适用于 Ubuntu 的 Debian Linux 平台包。 还要确保根据 Droplet 的体系结构选择 32 位或 64 位版本。 将安装包上传到您的每个 Droplet。

所有 Droplet 的安装说明都相同,因此请在所有 3 个 Droplet 上完成这些步骤。

在开始安装之前,必须安装 libaio1 包,因为它是一个依赖项:

sudo apt-get install libaio1

之后,安装 MySQL 集群包:

sudo dpkg -i mysql-cluster-gpl-7.4.11-debian7-x86_64.deb

现在您可以在目录/opt/mysql/server-5.6/中找到MySQL集群安装。 我们将特别处理所有二进制文件所在的 bin 目录 (/opt/mysql/server-5.6/bin/)。

应该在所有三个 Droplet 上执行相同的安装步骤,不管每个都有不同的功能 - 管理器或数据节点。

接下来,我们将在每个 Droplet 上配置 MySQL 集群管理器。

第 2 步 — 配置和启动集群管理器

在这一步中,我们将配置 MySQL 集群管理器 (manager.mysql.cluster)。 它的正确配置将确保数据节点之间的正确同步和负载分配。 所有命令都应在 Droplet manager.mysql.cluster 上执行。

集群管理器是必须在任何集群中启动的第一个组件。 它需要一个配置文件,该文件作为参数传递给其二进制文件。 为方便起见,我们将使用文件 /var/lib/mysql-cluster/config.ini 进行配置。

manager.mysql.cluster Droplet 上,首先创建该文件所在的目录(/var/lib/mysql-cluster):

sudo mkdir /var/lib/mysql-cluster 

然后创建一个文件并开始使用 nano 编辑它:

sudo nano /var/lib/mysql-cluster/config.ini

该文件应包含以下代码:

/var/lib/mysql-cluster/config.ini

[ndb_mgmd]
# Management process options:
hostname=manager.mysql.cluster  # Hostname of the manager
datadir=/var/lib/mysql-cluster  # Directory for the log files

[ndbd]
hostname=node1.mysql.cluster    # Hostname of the first data node
datadir=/usr/local/mysql/data   # Remote directory for the data files

[ndbd]
hostname=node2.mysql.cluster    # Hostname of the second data node
datadir=/usr/local/mysql/data   # Remote directory for the data files

[mysqld]
# SQL node options:
hostname=manager.mysql.cluster  # In our case the MySQL server/client is on the same Droplet as the cluster manager

对于上述每个组件,我们定义了一个 hostname 参数。 这是一项重要的安全措施,因为仅允许指定的主机名连接到管理器并按照其指定的角色参与集群。

此外,hostname 参数指定服务将在哪个接口上运行。 这很重要,对安全也很重要,因为在我们的例子中,上面的主机名指向我们在 /etc/hosts 文件中指定的私有 IP。 因此,您无法从专用网络外部访问上述任何服务。

在上述文件中,您可以添加更多冗余组件,例如数据节点 (ndbd) 或 MySQL 服务器 (mysqld),只需以完全相同的方式定义其他实例。

现在您可以通过执行 ndb_mgmd 二进制文件并使用 -f 参数指定配置文件来首次启动管理器,如下所示:

sudo /opt/mysql/server-5.6/bin/ndb_mgmd -f /var/lib/mysql-cluster/config.ini

您应该会看到一条关于成功启动的消息,类似于:

Output of ndb_mgmdMySQL Cluster Management Server mysql-5.6.29 ndb-7.4.11

您可能希望通过服务器自动启动管理服务。 GA 集群版本没有附带合适的启动脚本,但网上有一些可用的。 一开始您只需将启动命令添加到 /etc/rc.local 文件中,该服务将在启动过程中自动启动。 不过,首先,您必须确保在服务器启动期间执行 /etc/rc.local。 在 Ubuntu 16.04 中,这需要运行一个附加命令:

sudo systemctl enable rc-local.service

然后打开文件/etc/rc.local进行编辑:

sudo nano /etc/rc.local

exit 行之前添加启动命令,如下所示:

/etc/rc.local

...
/opt/mysql/server-5.6/bin/ndb_mgmd -f /var/lib/mysql-cluster/config.ini
exit 0

保存并退出文件。

集群管理器不必一直运行。 它可以在不停机的情况下启动、停止和重新启动集群。 仅在集群节点和 MySQL 服务器/客户端的初始启动期间才需要。

第 3 步 — 配置和启动数据节点

接下来,我们将配置数据节点(node1.mysql.clusternode2.mysql.cluster)来存储数据文件并正确支持 NDB 引擎。 所有命令都应在两个节点上执行。 您可以先从 node1.mysql.cluster 开始,然后在 node2.mysql.cluster 上重复完全相同的步骤。

数据节点从标准 MySQL 配置文件 /etc/my.cnf 尤其是 [mysql_cluster] 行之后的部分读取配置。 用 nano 创建这个文件并开始编辑它:

sudo nano /etc/my.cnf

像这样指定管理器的主机名:

/etc/my.cnf

[mysql_cluster]
ndb-connectstring=manager.mysql.cluster

保存并退出文件。

指定管理器的位置是节点引擎启动所需的唯一配置。 其余配置将直接从管理器中获取。 在我们的示例中,数据节点将根据管理器的配置发现其数据目录为 /usr/local/mysql/data。 必须在节点上创建此目录。 您可以使用以下命令执行此操作:

sudo mkdir -p /usr/local/mysql/data

之后,您可以使用以下命令首次启动数据节点:

sudo /opt/mysql/server-5.6/bin/ndbd

成功启动后,您应该会看到类似的输出:

Output of ndbd2016-05-11 16:12:23 [ndbd] INFO     -- Angel connected to 'manager.mysql.cluster:1186'
2016-05-11 16:12:23 [ndbd] INFO     -- Angel allocated nodeid: 2

您应该使用服务器自动启动 ndbd 服务。 GA 集群版本也没有为此提供合适的启动脚本。 就像我们对集群管理器所做的那样,让我们将启动命令添加到 /etc/rc.local 文件中。 同样,您必须确保在服务器启动期间使用以下命令执行 /etc/rc.local

sudo systemctl enable rc-local.service

然后打开文件/etc/rc.local进行编辑:

sudo nano /etc/rc.local

exit 行之前添加启动命令,如下所示:

/etc/rc.local

...
/opt/mysql/server-5.6/bin/ndbd
exit 0

保存并退出文件。

完成第一个节点后,在另一个节点上重复完全相同的步骤,在我们的示例中为 node2.mysql.cluster

第 4 步 — 配置和启动 MySQL 服务器和客户端

标准 MySQL 服务器,例如 Ubuntu 的默认 apt 存储库中可用的服务器,不支持 MySQL 集群引擎 NDB。 这就是您需要自定义 MySQL 服务器安装的原因。 我们已经安装在三个 Droplet 上的集群包也附带了一个 MySQL 服务器和一个客户端。 如前所述,我们将在管理节点 (manager.mysql.cluster) 上使用 MySQL 服务器和客户端。

配置再次存储为默认的 /etc/my.cnf 文件。 在 manager.mysql.cluster 上,打开配置文件:

sudo nano /etc/my.cnf

然后将以下内容添加到其中:

/etc/my.cnf

[mysqld]
ndbcluster # run NDB storage engine
...

保存并退出文件。

根据最佳实践,MySQL 服务器应该在属于自己的组(同样是 mysql)的自己的用户(mysql)下运行。 所以让我们首先创建组:

sudo groupadd mysql

然后创建属于该组的 mysql 用户,并通过将其 shell 路径设置为 /bin/false 来确保它不能使用 shell,如下所示:

sudo useradd -r -g mysql -s /bin/false mysql

自定义 MySQL 服务器安装的最后一个要求是创建默认数据库。 您可以使用以下命令执行此操作:

sudo /opt/mysql/server-5.6/scripts/mysql_install_db --user=mysql

为了启动 MySQL 服务器,我们将使用 /opt/mysql/server-5.6/support-files/mysql.server 中的启动脚本。 将其复制到名称为 mysqld 下的默认初始化脚本目录,如下所示:

sudo cp /opt/mysql/server-5.6/support-files/mysql.server /etc/init.d/mysqld

启用启动脚本并使用以下命令将其添加到默认运行级别:

sudo systemctl enable mysqld.service

现在我们可以使用以下命令第一次手动启动 MySQL 服务器:

sudo systemctl start mysqld

作为 MySQL 客户端,我们将再次使用集群安装附带的自定义二进制文件。 它具有以下路径:/opt/mysql/server-5.6/bin/mysql。 为方便起见,让我们在默认的 /usr/bin 路径中创建指向它的符号链接:

sudo ln -s /opt/mysql/server-5.6/bin/mysql /usr/bin/

现在您可以通过简单地键入 mysql 从命令行启动客户端,如下所示:

mysql

您应该看到类似于以下内容的输出:

Output of ndb_mgmdWelcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.29-ndb-7.4.11-cluster-gpl MySQL Cluster Community Server (GPL)

要退出 MySQL 提示,只需键入 quit 或同时按 CTRL-D

以上是第一次检查表明 MySQL 集群、服务器和客户端都在工作。 接下来,我们将通过更详细的测试来确认集群是否正常工作。

测试集群

至此,我们的一个客户端、一个服务器、一个管理器和两个数据节点的简单 MySQL 集群应该已经完成。 从集群管理器 Droplet (manager.mysql.cluster) 使用以下命令打开管理控制台:

sudo /opt/mysql/server-5.6/bin/ndb_mgm

现在提示应该更改为集群管理控制台。 它看起来像这样:

Inside the ndb_mgm console-- NDB Cluster -- Management Client --
ndb_mgm>

一旦进入控制台,像这样执行命令 SHOW

SHOW

您应该会看到与此类似的输出:

Output of ndb_mgmConnected to Management Server at: manager.mysql.cluster:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=2    @10.135.27.42  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 0, *)
id=3    @10.135.27.43  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @10.135.27.51  (mysql-5.6.29 ndb-7.4.11)

[mysqld(API)]   1 node(s)
id=4    @10.135.27.51  (mysql-5.6.29 ndb-7.4.11)

上图显示有两个数据节点,id 为 2 和 3。 他们是活跃的和连接的。 还有一个 ID 为 1 的管理节点和一个 ID 为 4 的 MySQL 服务器。 您可以通过使用命令 STATUS 键入其编号来找到有关每个 id 的更多信息,如下所示:

2 STATUS
``` 

The above command would show you the status of node 2 along with its MySQL and NDB versions:

```
[secondary_label Output of ndb_mgm]
Node 2: started (mysql-5.6.29 ndb-7.4.11)
```

To exit the management console type `quit`.

The management console is very powerful and gives you many other options for managing the cluster and its data, including creating an online backup. For more information check the [official documentation](http://dev.mysql.com/doc/refman/5.6/en/mysql-cluster-management.html "here").

Let's have a test with the MySQL client now. From the same Droplet, start the client with the `mysql` command for the MySQL root user. Please recall that we have created a symlink to it earlier.

```command
mysql -u root
```

\Your console will change to the MySQL client console. Once inside the MySQL client, run the command:

```custom_prefix(mysql>)
SHOW ENGINE NDB STATUS \G
```

Now you should see all the information about the NDB cluster engine starting with the connection details:

```
[secondary_label Output of mysql]

*************************** 1. row ***************************
  Type: ndbcluster
  Name: connection
Status: cluster_node_id=4, connected_host=manager.mysql.cluster, connected_port=1186, number_of_data_nodes=2, number_of_ready_data_nodes=2, connect_count=0
...
```

The most important information from above is the number of ready nodes — 2. This redundancy will allow your MySQL cluster to continue operating even if one of the data nodes fails while. At the same time your SQL queries will be load balanced to the two nodes.

You can try shutting down one of the data nodes in order to test the cluster stability. The simplest thing would be just to restart the whole Droplet in order to have a full test of the recovery process. You will see the value of `number_of_ready_data_nodes` change to `1` and back to `2` again as the node is restarted.

### Working with the NDB Engine

To see how the cluster really works, let's create a new table with the NDB engine and insert some data into it. Please note that in order to use the cluster functionality, the engine must be NDB. If you use InnoDB (default) or any other engine other than NDB, you will not make use of the cluster. 

First, let's create a database called `cluster` with the command:

```custom_prefix(mysql>)
CREATE DATABASE cluster;
```

Next, switch to the new database:

```custom_prefix(mysql>)
USE cluster;
```

Now, create a simple table called `cluster_test` like this:

```custom_prefix(mysql>)
CREATE TABLE cluster_test (name VARCHAR(20), value VARCHAR(20)) ENGINE=ndbcluster;
```

We have explicitly specified above the engine `ndbcluster` in order to make use of the cluster. Next, we can start inserting data with a query like this:

```custom_prefix(mysql>)
INSERT INTO cluster_test (name,value) VALUES('some_name','some_value');
```

To verify the data has been inserted, run a select query like this:

```custom_prefix(mysql>)
SELECT * FROM cluster_test;
```

When you are inserting and selecting data like this, you are load-balancing your queries between all the available data node, which are two in our example. With this scaling out you benefit both in terms of stability and performance.

## Conclusion

As we have seen in this article, setting up a MySQL cluster can be simple and easy. Of course, there are many more advanced options and features which are worth mastering before bringing the cluster to your production environment. As always, make sure to have an adequate testing process because some problems could be very hard to solve later. For more information and further reading please go to the official documentation for [MySQL cluster](http://dev.mysql.com/doc/refman/5.6/en/mysql-cluster.html).