如何在CentOS7服务器上使用MariaDB配置Galera集群
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
集群通过将更改分布到不同的服务器来增加数据库的高可用性。 如果其中一个实例发生故障,其他实例可以快速继续服务。
集群有两种通用配置,主动-被动和主动-主动。 在主动-被动集群中,所有写入都在单个主动服务器上完成,然后复制到一个或多个被动服务器,这些被动服务器准备仅在主动服务器发生故障时接管。 一些主动-被动集群还允许在被动节点上进行 SELECT
操作。 在主动-主动集群中,每个节点都是可读写的,对一个节点所做的更改会复制到所有节点。
MariaDB 是一个开源的关系型数据库系统,完全兼容流行的 MySQL RDBMS 系统。 您可以在 页面 阅读 MariaDB 的官方文档。 Galera 是一个数据库集群解决方案,使您能够使用同步复制设置多主集群。 Galera 自动处理保持不同节点上的数据同步,同时允许您向集群中的任何节点发送读写查询。 您可以在官方 文档页面 上了解有关 Galera 的更多信息。
在本指南中,您将配置一个主动-主动 MariaDB Galera 集群。 出于演示目的,您将配置和测试三个将充当集群中节点的 CentOS 7 Droplet。 这是最小的可配置集群。
先决条件
要继续,除了以下内容外,您还需要一个 DigitalOcean 帐户:
- 三个启用了私有网络的 CentOS 7 Droplet,每个都有一个具有
sudo
权限的非 root 用户并启用了防火墙。 要在三个 Droplet 上设置专用网络,请遵循我们的专用网络快速入门指南。 如需帮助设置具有 sudo 权限的非 root 用户,请按照我们的 CentOS 7 初始服务器设置教程进行操作。 要设置防火墙,请查看新 CentOS 7 服务器的其他推荐步骤的配置基本防火墙步骤。
虽然本教程中的步骤是针对 DigitalOcean Droplets 编写和测试的,但其中许多应该也适用于启用了私有网络的非 DigitalOcean 服务器。
第 1 步 — 将 MariaDB 存储库添加到所有服务器
在此步骤中,您将向三台服务器中的每台服务器添加相关的 MariaDB 包存储库,以便您能够安装本教程中使用的正确版本的 MariaDB。 在所有三台服务器上更新存储库后,您就可以安装 MariaDB。
关于 MariaDB 需要注意的一点是,它起源于 MySQL 的替代品,因此在许多配置文件和启动脚本中,您会看到 mysql
而不是 mariadb
。 在许多情况下,这些是可以互换的。 为了一致性起见,我们将在本指南中使用 mariadb
,其中任何一个都可以工作。
在本教程中,您将使用 MariaDB 版本 10.4。 由于此版本不包含在默认的 CentOS 存储库中,因此您首先将由 MariaDB 项目维护的外部 CentOS 存储库添加到您的所有三个服务器。
注意: MariaDB 是一个备受推崇的提供商,但并非所有外部存储库都是可靠的。 请务必仅从受信任的来源安装。
首先,您将通过使用文本编辑器创建存储库文件来添加 MariaDB 存储库密钥。 本教程将使用 vi
:
sudo vi /etc/yum.repos.d/mariadb.repo
接下来,通过按 i
进入插入模式,将以下内容添加到文件中,然后添加以下内容:
/etc/yum.repos.d/mariadb.repo
[mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.4/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
按 esc
键返回正常模式,然后键入 :wq
保存并退出文件。 如果您想了解有关文本编辑器 vi
及其前身 vim
的更多信息,请查看我们关于 在云服务器上安装和使用 Vim 文本编辑器 的教程]。
创建存储库文件后,使用以下命令启用它:
sudo yum makecache --disablerepo='*' --enablerepo='mariadb'
makecache
命令缓存存储库元数据,以便包管理器可以安装 MariaDB,其中 --disablerepo
和 --enablerepo
将命令定位到您的 mariadb
存储库文件刚刚创建。
您将收到以下输出:
OutputLoaded plugins: fastestmirror Loading mirror speeds from cached hostfile mariadb | 2.9 kB 00:00:00 (1/3): mariadb/primary_db | 43 kB 00:00:00 (2/3): mariadb/other_db | 8.3 kB 00:00:00 (3/3): mariadb/filelists_db | 238 kB 00:00:00 Metadata Cache Created
在第一台服务器上启用存储库后,对第二台和第三台服务器重复此操作。
现在您已在所有三台服务器上成功添加了包存储库,您可以在下一部分中安装 MariaDB。
第 2 步 — 在所有服务器上安装 MariaDB
在这一步中,您将在您的三台服务器上安装实际的 MariaDB 包。
从版本 10.1
开始,MariaDB Server 和 MariaDB Galera Server 包合并,所以安装 MariaDB-server
将自动安装 Galera 和几个依赖项:
sudo yum install MariaDB-server MariaDB-client
系统将要求您确认是否要继续安装。 输入 yes
继续安装。 然后将提示您接受用于验证 MariaDB 包的 GPG 密钥。 再次输入yes
。
安装完成后,通过运行以下命令启动 mariadb
服务:
sudo systemctl start mariadb
通过执行以下命令使 mariadb
服务在启动时自动启动:
sudo systemctl enable mariadb
从 MariaDB 版本 10.4
开始,root MariaDB 用户默认没有密码。 要为 root 用户设置密码,首先登录 MariaDB:
sudo mysql -uroot
进入 MariaDB shell 后,通过执行以下语句更改密码,将 your_password
替换为您想要的密码:
set password = password("your_password");
您将看到以下输出,表明密码设置正确:
OutputQuery OK, 0 rows affected (0.001 sec)
通过运行以下命令退出 MariaDB shell:
quit;
如果您想了解有关 SQL 的更多信息或需要快速复习,请查看我们的 MySQL 教程。
您现在拥有开始配置集群所需的所有部分,但是由于您将在后续步骤中依赖 rsync
和 policycoreutils-python
来同步服务器并控制安全增强型 Linux( SELinux),请确保在继续之前已安装它们:
sudo yum install rsync policycoreutils-python
这将确认 rsync
和 policycoreutils-python
的最新版本已经可用,或者会提示您升级或安装它。
完成这些步骤后,对其他两台服务器重复这些步骤。
现在您已经在三台服务器上成功安装了 MariaDB,您可以继续下一节中的配置步骤。
第 3 步 — 配置第一个节点
在这一步中,您将配置您的第一个 Galera 节点。 集群中的每个节点都需要具有几乎相同的配置。 因此,您将在第一台机器上完成所有配置,然后将其复制到其他节点。
默认情况下,MariaDB 配置为检查 /etc/mysql/conf.d
目录以从以 .cnf
结尾的文件中获取其他配置设置。 在此目录中创建一个包含所有集群特定指令的文件:
sudo vi /etc/my.cnf.d/galera.cnf
将以下配置添加到文件中。 该配置指定了不同的集群选项、有关当前服务器和集群中其他服务器的详细信息以及与复制相关的设置。 请注意,配置中的 IP 地址是您各自服务器的私有地址; 用适当的 IP 地址替换突出显示的行:
/etc/my.cnf.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/lib64/galera-4/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 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
必须与您所在机器的地址匹配,但您可以选择任何您想要的名称,以帮助您识别日志文件中的节点。
当您对集群配置文件感到满意时,将内容复制到剪贴板并保存并关闭文件。
现在您已经成功配置了第一个节点,您可以继续在下一部分中配置其余节点。
第 4 步 — 配置剩余节点
在此步骤中,您将配置剩余的两个节点。 在第二个节点上,打开配置文件:
sudo vi /etc/mysql/my.cnf.d/galera.cnf
粘贴您从第一个节点复制的配置,然后更新 Galera Node Configuration
以使用您正在设置的特定节点的 IP 地址或可解析域名。 最后,更新其名称,您可以将其设置为任何有助于您在日志文件中识别节点的名称:
/etc/mysql/my.cnf.d/galera.cnf
. . . # Galera Node Configuration wsrep_node_address="This_Node_IP" wsrep_node_name="This_Node_Name" . . .
保存并退出文件。
完成这些步骤后,在第三个节点上重复它们。
在所有节点上配置 Galera 后,您几乎可以启动集群了。 但在此之前,请确保在您的防火墙中打开了相应的端口,并且已经为 Galera 创建了 SELinux 策略。
第 5 步 — 在每台服务器上打开防火墙
在此步骤中,您将配置防火墙,以便打开节点间通信所需的端口。
在每台服务器上,通过运行以下命令检查您在先决条件部分设置的防火墙的状态:
sudo firewall-cmd --list-all
在这种情况下,仅允许 SSH、DHCP、HTTP 和 HTTPS 流量通过:
Outputpublic target: default icmp-block-inversion: no interfaces: sources: services: ssh dhcpv6-client http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
如果您现在尝试启动集群,它将失败,因为防火墙会阻止节点之间的连接。 要解决此问题,请添加规则以允许 MariaDB 和 Galera 流量通过。
Galera 可以使用四个端口:
3306
用于 MariaDB 客户端连接和使用mysqldump
方法的状态快照传输。4567
用于 Galera 集群复制流量。 多播复制在此端口上同时使用 UDP 传输和 TCP。4568
对于 增量状态转移 或 IST,集群中其他节点接收缺失状态的过程。4444
对于所有其他 State Snapshot Transfers 或 SST,加入节点从施主节点获取其状态和数据的机制。
在此示例中,您将在进行设置时打开所有四个端口。 一旦您确认复制工作正常,您需要关闭所有您实际上不使用的端口,并将流量限制在集群中的服务器上。
使用以下命令打开端口:
sudo firewall-cmd --permanent --zone=public --add-port=3306/tcp sudo firewall-cmd --permanent --zone=public --add-port=4567/tcp sudo firewall-cmd --permanent --zone=public --add-port=4568/tcp sudo firewall-cmd --permanent --zone=public --add-port=4444/tcp sudo firewall-cmd --permanent --zone=public --add-port=4567/udp
在这里使用 --zone=public
和 --add-port=
,firewall-cmd
将这些端口开放给公共流量。 --permanent
确保这些规则持续存在。
注意: 根据您的服务器上运行的其他内容,您可能希望立即限制访问。 要了解有关如何使用 FirewallD 的更多信息,请参阅我们的教程 如何在 CentOS 7 上使用 FirewallD 设置防火墙。
现在,通过执行以下命令将每个服务器添加到 public
区域,将突出显示的文本替换为节点的相应私有 IP 地址:
sudo firewall-cmd --permanent --zone=public --add-source=galera-node-1-ip/32 sudo firewall-cmd --permanent --zone=public --add-source=galera-node-2-ip/32 sudo firewall-cmd --permanent --zone=public --add-source=galera-node-3-ip/32
重新加载防火墙以应用更改:
sudo firewall-cmd --reload
在第一个节点上配置防火墙后,在第二个和第三个节点上创建相同的防火墙设置。
现在您已经成功配置了防火墙,您可以在下一步中创建 SELinux 策略了。
第 6 步 — 创建 SELinux 策略
在本节中,您将创建一个 SELinux 策略,该策略将允许集群中的所有节点能够相互通信并执行集群操作。
SELinux 是一个 Linux 内核模块,它通过支持访问控制和强制访问控制策略来提高操作系统的安全性。 它在 CentOS 7 上默认启用,并限制 MariaDB 守护进程执行许多活动。
为了创建策略,您将在 SELinux 模式设置为 MySQL 允许的集群上执行各种活动。 然后,您将从记录的事件中创建一个策略,并最终在策略安装成功后将 SELinux 模式设置为强制执行。
首先,通过在所有三台服务器上运行以下命令来允许访问相关端口:
sudo semanage port -a -t mysqld_port_t -p tcp 4567 sudo semanage port -a -t mysqld_port_t -p udp 4567 sudo semanage port -a -t mysqld_port_t -p tcp 4568 sudo semanage port -a -t mysqld_port_t -p tcp 4444
注意: 当允许访问其中一些端口时,您可能会收到 ValueError
。 这意味着该端口的 SELinux 状态已经设置,在这种情况下不会影响本教程的进程。
在这些命令中,您使用带有 -a
标志的 SELinux 管理工具 semanage
添加指定端口并忽略数据库服务器。
接下来,在所有三台服务器上运行以下命令,将 MySQL SELinux 域临时设置为许可模式。
sudo semanage permissive -a mysqld_t
此命令可能需要一分钟才能完成,并且不会显示任何输出。
接下来,停止所有节点上的数据库服务器,以便您能够使用共享的 SELinux 策略引导数据库集群。 为此,请在所有三个节点上运行以下命令:
sudo systemctl stop mariadb
现在,引导集群以生成将添加到 SELinux 策略的节点间通信事件。 在第一个节点上,通过执行以下命令来引导集群:
sudo galera_new_cluster
通过在第一个节点上运行以下命令,为记录 SST 事件的特定目的创建数据库和表:
mysql -u root -p -e 'CREATE DATABASE selinux; CREATE TABLE selinux.selinux_policy (id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)); INSERT INTO selinux.selinux_policy VALUES ();'
现在在第二个节点上启动服务器:
sudo systemctl start mariadb
然后在第三个节点上执行相同的操作:
sudo systemctl start mariadb
您将看不到前面命令的任何输出。 要生成 IST 事件,请在所有三个服务器上执行以下命令:
mysql -u root -p -e 'INSERT INTO selinux.selinux_policy VALUES ();'
现在通过在所有三台服务器上执行以下命令来创建并启用 SELinux 策略:
sudo grep mysql /var/log/audit/audit.log | sudo audit2allow -M Galera
第一个命令在 audit.log
文件中搜索生成的事件,并将它们通过管道传送到由 audit2allow
工具生成的名为 Galera.pp
的模块。 这将导致以下输出:
Output******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i Galera.pp
接下来,按照输出中的说明使用以下命令安装生成的模块:
sudo semodule -i Galera.pp
现在该策略处于活动状态,请禁用 MariaDB 服务器的许可模式:
sudo semanage permissive -d mysqld_t
现在您已经成功创建并启用了 SELinux 策略,您可以在下一部分中启动集群了。
第 7 步 — 启动集群
在此步骤中,您将启动 MariaDB 集群。 首先,您需要停止正在运行的 MariaDB 服务,以便您可以使集群联机。
在所有三台服务器上停止 MariaDB
停止 MariaDB 服务时,以特定顺序在您的服务器上执行此操作非常重要。 此关闭顺序可确保第一个节点在启动时能够安全地引导集群。
首先,在第三个节点上运行以下命令:
sudo systemctl stop mariadb
接下来,停止第二个节点上的服务:
sudo systemctl stop mariadb
最后,停止第一个节点上的服务:
sudo systemctl stop mariadb
systemctl
不会显示所有服务管理命令的结果,因此为确保您成功,请在您的每台服务器上使用以下命令:
sudo systemctl status mariadb
最后一行将如下所示:
Output. . . Apr 26 03:34:23 galera-node-01 systemd[1]: Stopped MariaDB 10.4.4 database server.
在所有服务器上关闭 mariadb
后,您就可以继续了。
启动第一个节点
要启动第一个节点,您需要使用特殊的启动脚本。 按照您配置集群的方式,每个上线的节点都会尝试连接到其 galera.cnf
文件中指定的至少一个其他节点以获取其初始状态。 如果不使用允许 systemd 传递 --wsrep-new-cluster
参数的 galera_new_cluster
脚本,正常的 systemctl start mariadb
将失败,因为没有运行节点来连接第一个节点。
sudo galera_new_cluster
此命令在成功执行时不会显示任何输出。 当此脚本成功时,该节点被注册为集群的一部分,您可以使用以下命令查看它:
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
您将看到以下输出,表明集群中有一个节点:
Output+--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 1 | +--------------------+-------+
其余节点上,可以正常启动mariadb
。 他们将搜索集群列表中在线的任何成员,因此当他们找到一个时,他们将加入集群。
调出第二个节点
现在您可以启动第二个节点。 开始mariadb
:
sudo systemctl start mariadb
成功执行后不会显示任何输出。 随着每个节点上线,您将看到集群大小增加:
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
您将看到以下输出,表明第二个节点已加入集群并且总共有两个节点。
Output+--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 2 | +--------------------+-------+
调出第三个节点
现在是启动第三个节点的时候了。 开始mariadb
:
sudo systemctl start mariadb
运行以下命令以查找集群大小:
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
您将看到以下输出,这表明第三个节点已加入集群,并且集群中的节点总数为三个。
Output+--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 3 | +--------------------+-------+
至此,整个集群在线,通信成功。 接下来,您可以通过在下一节中测试复制来确保工作设置。
第 8 步 — 测试复制
到目前为止,您已经完成了这些步骤,以便您的集群可以执行从任何节点到任何其他节点的复制,称为主动-主动复制。 按照以下步骤测试并查看复制是否按预期工作。
写入第一个节点
您将首先在您的第一个节点上进行数据库更改。 以下命令将创建一个名为 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,它允许您非常快速地设置新节点,而无需活动节点的大中断。 这不会影响实际的复制,但在初始化节点时是一个问题。
如果您想继续学习 SQL 数据库,请查看我们的 如何管理 SQL 数据库 文章。