如何在Debian10服务器上使用MariaDB配置Galera集群
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
集群通过将更改分布到不同的服务器来增加数据库的高可用性。 如果其中一个实例发生故障,其他实例可以快速继续服务。
集群有两种通用配置,主动-被动和主动-主动。 在主动-被动集群中,所有写入都在单个主动服务器上完成,然后复制到一个或多个被动服务器,这些被动服务器准备仅在主动服务器发生故障时接管。 一些主动-被动集群还允许在被动节点上进行 SELECT
操作。 在主动-主动集群中,每个节点都是可读写的,对一个节点所做的更改会复制到所有节点。
MariaDB 是一个开源的关系型数据库系统,完全兼容流行的 MySQL RDBMS 系统。 您可以在 页面 阅读 MariaDB 的官方文档。 Galera 是一个数据库集群解决方案,使您能够使用同步复制设置多主集群。 Galera 自动处理保持不同节点上的数据同步,同时允许您向集群中的任何节点发送读写查询。 您可以在官方 文档页面 上了解有关 Galera 的更多信息。
在本指南中,您将配置一个主动-主动 MariaDB Galera 集群。 出于演示目的,您将配置和测试三个充当集群节点的 Debian 10 服务器。 这是最小的可配置集群。
先决条件
要继续,除了以下内容外,您还需要一个 DigitalOcean 帐户:
- 三台启用了私有网络的 Debian 10 服务器,每台服务器都有一个具有
sudo
权限的非 root 用户。 要在三个 Droplet 上设置专用网络,请遵循我们的专用网络快速入门指南。 如需帮助设置具有 sudo 权限的非 root 用户,请按照我们的 Debian 10 初始服务器设置教程进行操作。
虽然本教程中的步骤是针对 DigitalOcean Droplets 编写和测试的,但其中大部分也应该适用于启用了私有网络的非 DigitalOcean 服务器。
第 1 步 — 将 MariaDB 存储库添加到所有服务器
在此步骤中,您将向三台服务器中的每台服务器添加相关的 MariaDB 包存储库,以便您能够安装本教程中使用的正确版本的 MariaDB。 在所有三台服务器上更新存储库后,您就可以安装 MariaDB。
关于 MariaDB 需要注意的一点是,它起源于 MySQL 的替代品,因此在许多配置文件和启动脚本中,您会看到 mysql
而不是 mariadb
。 为了一致性起见,我们将在本指南中使用 mysql
,其中任何一个都可以工作。
在本教程中,您将使用 MariaDB 版本 10.4。 由于此版本不包含在默认的 Debian 存储库中,因此您首先将由 MariaDB 项目维护的外部 Debian 存储库添加到您的所有三台服务器。
要添加存储库,您首先需要安装 dirmngr
和 software-properties-common
软件包。 dirmngr
是用于管理存储库证书和密钥的服务器。 software-properties-common
是一个允许轻松添加和更新源存储库位置的软件包。 通过运行安装这两个包:
sudo apt install dirmngr software-properties-common
注意: MariaDB 是一个备受推崇的提供商,但并非所有外部存储库都是可靠的。 请务必仅从受信任的来源安装。
您将使用 apt-key
命令添加 MariaDB 存储库密钥,APT 包管理器将使用该命令来验证包是否真实:
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
在数据库中拥有可信密钥后,您可以使用以下命令添加存储库:
sudo add-apt-repository 'deb [arch=amd64] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.4/debian buster main'
添加存储库后,运行 apt update
以包含来自新存储库的包清单:
sudo apt update
在第一台服务器上完成此步骤后,对第二台和第三台服务器重复此步骤。
现在您已在所有三台服务器上成功添加了包存储库,您可以在下一部分中安装 MariaDB。
第 2 步 — 在所有服务器上安装 MariaDB
在这一步中,您将在您的三台服务器上安装实际的 MariaDB 包。
从版本 10.1
开始,MariaDB Server 和 MariaDB Galera Server 包合并,所以安装 mariadb-server
将自动安装 Galera 和几个依赖项:
sudo apt install mariadb-server
系统将要求您确认是否要继续安装。 输入 yes
继续安装。
从 MariaDB 版本 10.4
开始,root MariaDB 用户默认没有密码。 要为 root 用户设置密码,首先登录 MariaDB:
sudo mysql -uroot
进入 MariaDB shell 后,通过执行以下语句更改密码:
set password = password("your_password");
您将看到以下输出,表明密码设置正确:
OutputQuery OK, 0 rows affected (0.001 sec)
通过运行以下命令退出 MariaDB shell:
quit;
如果您想了解有关 SQL 的更多信息或需要快速复习,请查看我们的 MySQL 教程。
您现在拥有开始配置集群所需的所有部分,但由于您将在后续步骤中依赖 rsync
,因此请确保已安装它:
sudo apt install rsync
这将确认 rsync
的最新版本已经可用或提示您升级或安装它。
安装 MariaDB 并在第一台服务器上设置 root 密码后,对其他两台服务器重复这些步骤。
现在您已经在三台服务器上成功安装了 MariaDB,您可以继续下一节中的配置步骤。
第 3 步 — 配置第一个节点
在此步骤中,您将配置您的第一个节点。 集群中的每个节点都需要具有几乎相同的配置。 因此,您将在第一台机器上完成所有配置,然后将其复制到其他节点。
默认情况下,MariaDB 配置为检查 /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"
- 第一部分 修改或重新声明 MariaDB/MySQL 设置,使集群能够正常运行。 例如,Galera 不能与 MyISAM 或类似的非事务性存储引擎一起使用,并且
mysqld
不能绑定到localhost
的 IP 地址。 您可以在 Galera Cluster 系统配置页面 上了解更详细的设置。 - “Galera Provider Configuration”部分 配置提供 WriteSet 复制 API 的 MariaDB 组件。 这意味着在您的情况下是 Galera,因为 Galera 是 wsrep (WriteSet Replication) 提供程序。 您指定常规参数来配置初始复制环境。 这不需要任何自定义,但您可以了解更多关于 Galera 配置选项 的信息。
- “Galera Cluster Configuration”部分定义集群,通过IP地址或可解析的域名识别集群成员,并为集群创建一个名称,以确保成员加入正确的组。 您可以将
wsrep_cluster_name
更改为比test_cluster
更有意义的内容或保持原样,但您必须使用您的三台服务器的私有 IP 地址更新wsrep_cluster_address
。 - “Galera 同步配置”部分 定义了集群如何在成员之间进行通信和同步数据。 这仅用于节点上线时发生的状态传输。 对于您的初始设置,您使用的是
rsync
,因为它通常可用并且可以满足您现在的需要。 - “Galera Node Configuration”部分明确了当前服务器的IP地址和名称。 这在尝试诊断日志中的问题以及以多种方式引用每个服务器时很有帮助。
wsrep_node_address
必须与您所在机器的地址匹配,但您可以选择任何您想要的名称,以帮助您识别日志文件中的节点。
当您对集群配置文件感到满意时,将内容复制到剪贴板,保存并关闭文件。 使用 nano 文本编辑器,您可以通过按 CTRL+X
、键入 y
并按 ENTER
来执行此操作。
现在您已经成功配置了第一个节点,您可以继续在下一部分中配置其余节点。
第 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 步 — 启动集群
在此步骤中,您将启动 MariaDB 集群。 首先,您需要停止正在运行的 MariaDB 服务,以便您可以使集群联机。
在所有三台服务器上停止 MariaDB
在所有三台服务器上使用以下命令停止 MariaDB,以便您可以将它们恢复到集群中:
sudo systemctl stop mysql
systemctl
不会显示所有服务管理命令的结果,因此为确保成功,请使用以下命令:
sudo systemctl status mysql
如果最后一行如下所示,则命令成功:
Output. . . Apr 26 03:34:23 galera-node-01 systemd[1]: Stopped MariaDB 10.4.4 database server.
在所有服务器上关闭 mysql
后,您就可以继续了。
启动第一个节点
要启动第一个节点,您需要使用特殊的启动脚本。 按照您配置集群的方式,每个上线的节点都会尝试连接到其 galera.cnf
文件中指定的至少一个其他节点以获取其初始状态。 如果不使用允许 systemd 传递 --wsrep-new-cluster
参数的 galera_new_cluster
脚本,正常的 systemctl start mysql
将失败,因为没有运行节点来连接第一个节点。
sudo galera_new_cluster
此命令在成功执行时不会显示任何输出。 当此脚本成功时,该节点被注册为集群的一部分,您可以使用以下命令查看它:
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,它允许您非常快速地设置新节点,而无需活动节点的大中断。 这不会影响实际的复制,但在初始化节点时是一个问题。