如何在Ubuntu18.04服务器上使用MySQL配置Galera集群

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

作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。

介绍

集群通过将更改分布到不同的服务器来增加数据库的高可用性。 如果其中一个实例发生故障,其他实例可以快速继续服务。

集群有两种通用配置,主动-被动主动-主动。 在主动-被动集群中,所有写入都在单个主动服务器上完成,然后复制到一个或多个被动服务器,这些被动服务器准备仅在主动服务器发生故障时接管。 一些主动-被动集群还允许在被动节点上进行 SELECT 操作。 在主动-主动集群中,每个节点都是可读写的,对一个节点所做的更改会复制到所有节点。

MySQL是一个开源的关系型数据库管理系统,是SQL数据库的热门选择。 Galera 是一个数据库集群解决方案,使您能够使用同步复制设置多主集群。 Galera 自动处理保持不同节点上的数据同步,同时允许您向集群中的任何节点发送读写查询。 您可以在官方 文档页面 上了解有关 Galera 的更多信息。

在本指南中,您将配置一个主动-主动 MySQL Galera 集群。 出于演示目的,您将配置和测试三个 Ubuntu 18.04 Droplets,它们将充当集群中的节点。 这个数量的节点是最小的可配置集群。

先决条件

要继续,除了以下内容外,您还需要一个 DigitalOcean 帐户

  • 三个启用了私有网络的 Ubuntu 18.04 Droplet,每个都有一个具有 sudo 权限的非 root 用户。 要在三个 Droplet 上设置专用网络,请遵循我们的专用网络快速入门指南。 如需帮助设置具有 sudo 权限的非 root 用户,请按照我们的 Ubuntu 18.04 初始服务器设置教程进行操作。

虽然本教程中的步骤是针对 DigitalOcean Droplets 编写和测试的,但其中大部分也适用于启用了私有网络的非 DigitalOcean 服务器。

第 1 步 — 将 MySQL 存储库添加到所有服务器

在此步骤中,您将向三台服务器中的每台服务器添加相关的 MySQL 和 Galera 软件包存储库,以便您能够安装本教程中使用的正确版本的 MySQL 和 Galera。

笔记: 编码, the company behind Galera Cluster, maintains the Galera repository, but be aware that not all external repositories are reliable. Be sure to install only from trusted sources.


在本教程中,您将使用 MySQL 版本 5.7。 您将首先将 Galera 项目维护的外部 Ubuntu 存储库添加到您的所有三台服务器。

在所有三台服务器上更新存储库后,您就可以安装 MySQL 和 Galera。

首先,在您的所有三台服务器上,使用 apt-key 命令添加 Galera 存储库密钥,APT 包管理器将使用该命令来验证包是否真实:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv BC19DDBA

几秒钟后,您将收到以下输出:

OutputExecuting: /tmp/apt-key-gpghome.RG5cTZjQo0/gpg.1.sh --keyserver keyserver.ubuntu.com --recv BC19DDBA
gpg: key D669017EBC19DDBA: public key "Codership Oy <info@galeracluster.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

在每个服务器的数据库中拥有可信密钥后,您就可以添加存储库。 为此,请在每个服务器上的 /etc/apt/sources.list.d/ 目录中创建一个名为 galera.list 的新文件:

sudo nano /etc/apt/sources.list.d/galera.list

在文本编辑器中,添加以下行,这将使 APT 包管理器可以使用适当的存储库:

/etc/apt/sources.list.d/galera.list

deb http://releases.galeracluster.com/mysql-wsrep-5.7/ubuntu bionic main
deb http://releases.galeracluster.com/galera-3/ubuntu bionic main

保存并关闭每台服务器上的文件(按 CTRL + XY,然后按 ENTER)。

Codership 存储库现在可用于您的所有三个服务器。 但是,重要的是您指示 apt 优先使用 Codership 的存储库而不是其他存储库,以确保它安装创建 Galera 集群所需的软件补丁版本。 为此,请在每个服务器的 /etc/apt/preferences.d/ 目录中创建另一个名为 galera.pref 的新文件:

sudo nano /etc/apt/preferences.d/galera.pref

将以下行添加到文本编辑器:

/etc/apt/preferences.d/galera.pref

# Prefer Codership repository
Package: *
Pin: origin releases.galeracluster.com
Pin-Priority: 1001

保存并关闭该文件,然后在每台服务器上运行以下命令以包含来自新存储库的包清单:

sudo apt update

现在您已经在所有三台服务器上成功添加了包存储库,您可以在下一部分中安装 MySQL。

第 2 步 — 在所有服务器上安装 MySQL

在这一步中,您将在三台服务器上安装 MySQL 包。

在所有三台服务器上运行以下命令以安装修补以与 Galera 一起使用的 MySQL 版本以及 Galera 包。

sudo apt install galera-3 mysql-wsrep-5.7

系统将要求您确认是否要继续安装。 输入 Y 继续安装。 在安装过程中,您还将被要求为 MySQL 管理用户设置密码。 设置强密码并按 ENTER 继续。

安装 MySQL 后,您将禁用默认 AppArmor 配置文件以确保 Galera 正常运行,根据 官方 Galera 文档AppArmor 是 Linux 的内核模块,它通过安全配置文件为服务提供访问控制功能。

通过在每个服务器上执行以下命令来禁用 AppArmor:

sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/

此命令将 MySQL 配置文件的符号链接添加到 disable 目录,这会在启动时禁用配置文件。

然后,运行以下命令,删除内核中已经加载的 MySQL 定义。

sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

在第一台服务器上安装 MySQL 并禁用 AppArmor 配置文件后,对其他两台服务器重复这些步骤。

现在您已经在三台服务器上成功安装了 MySQL,您可以继续下一节中的配置步骤。

第 3 步 — 配置第一个节点

在此步骤中,您将配置您的第一个节点。 集群中的每个节点都需要具有几乎相同的配置。 因此,您将在第一台机器上完成所有配置,然后将其复制到其他节点。

默认情况下,MySQL 配置为检查 /etc/mysql/conf.d 目录以从以 .cnf 结尾的文件中获取其他配置设置。 在您的第一台服务器上,在此目录中创建一个包含所有集群特定指令的文件:

sudo nano /etc/mysql/conf.d/galera.cnf

将以下配置添加到文件中。 该配置指定了不同的集群选项、有关当前服务器和集群中其他服务器的详细信息以及与复制相关的设置。 请注意,配置中的 IP 地址是您各自服务器的私有地址; 用适当的 IP 地址替换突出显示的行。

/etc/mysql/conf.d/galera.cnf

[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Galera Provider Configuration
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so

# Galera Cluster Configuration
wsrep_cluster_name="test_cluster"
wsrep_cluster_address="gcomm://First_Node_IP,Second_Node_IP,Third_Node_IP"

# Galera Synchronization Configuration
wsrep_sst_method=rsync

# Galera Node Configuration
wsrep_node_address="This_Node_IP"
wsrep_node_name="This_Node_Name"
  • 第一部分 修改或重新断言 MySQL 设置,使集群能够正常运行。 例如,Galera 不能与 MyISAM 或类似的非事务性存储引擎一起使用,并且 mysqld 不能绑定到 localhost 的 IP 地址。 您可以在 Galera Cluster 系统配置页面 上了解更详细的设置。
  • “Galera Provider Configuration”部分配置提供WriteSet复制API的MySQL组件。 这意味着在您的情况下是 Galera,因为 Galera 是 wsrep (WriteSet Replication) 提供程序。 您指定常规参数来配置初始复制环境。 这不需要任何自定义,但您可以在文档 中了解有关 Galera 配置选项的更多信息。
  • “Galera Cluster Configuration”部分定义集群,通过IP地址或可解析的域名识别集群成员,并为集群创建一个名称,以确保成员加入正确的组。 您可以将 wsrep_cluster_name 更改为比 test_cluster 更有意义的内容或保持原样,但您必须使用您的三台服务器的私有 IP 地址更新 wsrep_cluster_address
  • Galera 同步配置部分 定义了集群如何在成员之间进行通信和同步数据。 这仅用于节点上线时发生的状态传输。 对于您的初始设置,您正在使用 rsync,因为它通常可用并且可以满足您现在的需要。
  • Galera节点配置部分明确了当前服务器的IP地址和名称。 这在尝试诊断日志中的问题以及以多种方式引用每个服务器时很有帮助。 wsrep_node_address 必须与您所在机器的地址匹配,但您可以选择任何您想要的名称,以帮助您识别日志文件中的节点。

当您对集群配置文件感到满意时,将内容复制到剪贴板,然后保存并关闭文件。

现在您已经成功配置了第一个节点,您可以继续在下一部分中配置其余节点。

第 4 步 — 配置剩余节点

在此步骤中,您将配置剩余的两个节点。 在第二个节点上,打开配置文件:

sudo nano /etc/mysql/conf.d/galera.cnf

粘贴您从第一个节点复制的配置,然后更新 Galera Node Configuration 以使用您正在设置的特定节点的 IP 地址或可解析域名。 最后,更新其名称,您可以将其设置为任何有助于您在日志文件中识别节点的名称:

/etc/mysql/conf.d/galera.cnf

. . .
# Galera Node Configuration
wsrep_node_address="This_Node_IP"
wsrep_node_name="This_Node_Name"
. . .

保存并退出文件。

完成这些步骤后,在第三个节点上重复它们。

您几乎已准备好启动集群,但在此之前,请确保在您的防火墙中打开了相应的端口。

第 5 步 — 在每台服务器上打开防火墙

在此步骤中,您将配置防火墙,以便打开节点间通信所需的端口。 在每台服务器上,通过运行以下命令检查防火墙的状态:

sudo ufw status

在这种情况下,只允许通过 SSH:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

由于在这种情况下只允许 SSH 流量,因此您需要为 MySQL 和 Galera 流量添加规则。 如果您尝试启动集群,它会因为这些防火墙规则而失败。

Galera 可以使用四个端口:

  • 3306 用于 MySQL 客户端连接和使用 mysqldump 方法的状态快照传输。
  • 4567 用于 Galera 集群复制流量。 多播复制在此端口上同时使用 UDP 传输和 TCP。
  • 4568 用于增量状态传输。
  • 4444 用于所有其他状态快照传输。

在此示例中,您将在进行设置时打开所有四个端口。 一旦您确认复制工作正常,您需要关闭所有您实际上不使用的端口,并将流量限制在集群中的服务器上。

使用以下命令打开端口:

sudo ufw allow 3306,4567,4568,4444/tcp
sudo ufw allow 4567/udp

注意: 根据您的服务器上运行的其他内容,您可能希望立即限制访问。 UFW Essentials: Common Firewall Rules and Commands 指南可以帮助解决这个问题。


在第一个节点上配置防火墙后,在第二个和第三个节点上创建相同的防火墙设置。

现在您已成功配置防火墙,您已准备好在下一步中启动集群。

第 6 步 — 启动集群

在这一步中,您将启动 MySQL Galera 集群。 但首先,您将启用 MySQL systemd 服务,这样 MySQL 将在服务器重新启动时自动启动。

使 MySQL 在所有三台服务器上启动时启动

在所有三台服务器上使用以下命令启用 MySQL systemd 服务:

sudo systemctl enable mysql

您将看到以下输出,这表明该服务已成功链接到启动服务列表:

OutputCreated symlink /etc/systemd/system/multi-user.target.wants/mysql.service → /lib/systemd/system/mysql.service.

现在您已启用 mysql 以在所有服务器上启动,您已准备好继续启动集群。

启动第一个节点

要启动第一个节点,您需要使用特殊的启动脚本。 按照您配置集群的方式,每个上线的节点都将尝试连接到其 galera.cnf 文件中指定的至少一个其他节点以获取其初始状态。 如果不使用允许 systemd 传递 --wsrep-new-cluster 参数的 mysqld_bootstrap 脚本,正常的 systemctl start mysql 将失败,因为没有节点为第一个节点运行与连接。

在您的第一台服务器上运行以下命令:

sudo mysqld_bootstrap

此命令在成功执行时不会显示任何输出。 当此脚本成功时,该节点被注册为集群的一部分,您可以使用以下命令查看它:

mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"

输入密码后,会看到如下输出,说明集群中有一个节点:

Output+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 1     |
+--------------------+-------+

其余节点上,可以正常启动mysql。 他们将搜索集群列表中任何在线的成员,当他们找到一个时,他们将加入集群。

调出第二个节点

现在您可以启动第二个节点。 开始mysql

sudo systemctl start mysql

成功执行后不会显示任何输出。 随着每个节点上线,您将看到集群大小增加:

mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"

您将看到以下输出,表明第二个节点已加入集群并且总共有两个节点。

Output+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 2     |
+--------------------+-------+

调出第三个节点

现在是启动第三个节点的时候了。 开始mysql

sudo systemctl start mysql

运行以下命令以查找集群大小:

mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"

您将看到以下输出,这表明第三个节点已加入集群,并且集群中的节点总数为三个。

Output+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+

至此,整个集群在线,通信成功。 接下来,您可以通过在下一节中测试复制来确保工作设置。

第 7 步 — 测试复制

到目前为止,您已经完成了这些步骤,以便您的集群可以执行从任何节点到任何其他节点的复制,称为主动-主动复制。 在此步骤中,您将测试并查看复制是否按预期工作。

写入第一个节点

您将首先在您的第一个节点上进行数据库更改。 以下命令将创建一个名为 playground 的数据库和一个名为 equipment 的表。

mysql -u root -p -e 'CREATE DATABASE playground;
CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));
INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");'

在前面的命令中,CREATE DATABASE 语句创建了一个名为 playground 的数据库。 CREATE 语句在 playground 数据库中创建一个名为 equipment 的表,该表具有一个名为 id 的自动递增标识符列和其他列。 type列、quant列和color列分别定义为存储设备的类型、数量和颜色。 INSERT 语句插入类型 slide、数量 2 和颜色 blue 的条目。

现在,您的表中有一个值。

在第二个节点上读写

接下来,查看第二个节点以验证复制是否正常工作:

mysql -u root -p -e 'SELECT * FROM playground.equipment;'

您在第一个节点上输入的数据将在第二个节点上可见,证明复制正在工作:

Output+----+-------+-------+-------+
| id | type  | quant | color |
+----+-------+-------+-------+
|  1 | slide |     2 | blue  |
+----+-------+-------+-------+

从同一个节点,将数据写入集群:

mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");'

在第三个节点上读写

从第三个节点,您可以通过再次查询表来读取所有这些数据:

mysql -u root -p -e 'SELECT * FROM playground.equipment;'

您将看到以下输出显示两行:

Output   +----+-------+-------+--------+
   | id | type  | quant | color  |
   +----+-------+-------+--------+
   |  1 | slide |     2 | blue   |
   |  2 | swing |    10 | yellow |
   +----+-------+-------+--------+

同样,您可以从此节点添加另一个值:

mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");'

在第一个节点上读取

回到第一个节点,您可以验证您的数据是否随处可用:

mysql -u root -p -e 'SELECT * FROM playground.equipment;'

您将看到以下输出,这表明行在第一个节点上可用。

Output   +----+--------+-------+--------+
   | id | type   | quant | color  |
   +----+--------+-------+--------+
   |  1 | slide  |     2 | blue   |
   |  2 | swing  |    10 | yellow |
   |  3 | seesaw |     3 | green  |
   +----+--------+-------+--------+

您现在已成功验证您可以写入所有节点并且复制正在正确执行。

结论

此时,您已经配置了一个工作的三节点 Galera 测试集群。 如果您计划在生产环境中使用 Galera 集群,建议您从不少于五个节点开始。

在生产使用之前,您可能需要查看一些 其他状态快照传输 (sst) 代理 ,例如 xtrabackup,它允许您快速设置新节点,而无需大量活动节点的中断。 这不会影响实际的复制,但在初始化节点时是一个问题。

您可能还对 MySQL 的其他集群解决方案感兴趣,在这种情况下,您可以查看我们的 How To Create a Multi-Node MySQL Cluster on Ubuntu 18.04 教程。 如果您想尝试托管数据库解决方案,请参阅我们的 DigitalOcean 托管数据库文档