介绍: 通过将更改分发到不同的服务器,集群为您的数据库增加了高可用性。如果其中一个实例失败,其他实例将迅速可用以继续提供服务。
集群有两种一般配置,即主备和主主。在主备集群中,所有写操作都在单个活动服务器上执行,然后复制到一个或多个被动服务器,这些被动服务器只在活动服务器故障时接管。一些主备集群还允许在被动节点上执行SELECT操作。在主主集群中,每个节点都是读写的,对一个节点所做的更改会被复制到所有节点。
MariaDB是一个开源的关系型数据库系统,与流行的MySQL RDBMS系统完全兼容。您可以在官方文档页面阅读有关MariaDB的官方文档。Galera是一种数据库集群解决方案,可通过同步复制设置多主集群。Galera会自动处理将不同节点上的数据保持同步,同时允许您将读写查询发送到集群中的任何节点。您可以在官方文档页面了解更多关于Galera的信息。
在本指南中,您将配置一个活动-活动的MariaDB Galera集群。出于演示目的,您将配置和测试三个CentOS 7 Droplets,它们将作为集群中的节点。这是最小的可配置集群。
先决条件: 要进行操作,您需要一个DigitalOcean账户,以及以下内容:
三个启用了私有网络的CentOS 7 Droplets,每个Droplet都有一个具有sudo特权的非root用户和启用了防火墙。 有关在三个Droplets上设置私有网络,请参阅我们的私有网络快速入门指南。 有关设置具有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
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
系统会要求您确认是否继续安装。输入 "是 "以继续安装。然后,系统会提示你接受验证 MariaDB 软件包的 GPG 密钥。再次输入 "是"。
安装完成后,运行以下命令启动 mariadb 服务:
sudo systemctl start mariadb
执行以下命令,使 mariadb 服务在启动时自动启动:
sudo systemctl enable mariadb
从 MariaDB 10.4 版开始,MariaDB 根用户默认没有密码。要为根用户设置密码,首先要登录 MariaDB:
sudo mysql -uroot
进入 MariaDB shell 后,执行以下语句更改密码,将 your_password 替换为所需密码:
set password = password("your_password"); OutputQuery OK, 0 rows affected (0.001 sec)quit;
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=ROWdefault-storage-engine=innodbinnodb_autoinc_lock_mode=2bind-address=0.0.0.0 # Galera Provider Configurationwsrep_on=ONwsrep_provider=/usr/lib64/galera-4/libgalera_smm.so # Galera Cluster Configurationwsrep_cluster_name="test_cluster"wsrep_cluster_address="gcomm://First_Node_IP,Second_Node_IP,Third_Node_IP" # Galera Synchronization Configurationwsrep_sst_method=rsync # Galera Node Configurationwsrep_node_address="This_Node_IP"wsrep_node_name="This_Node_Name"
第一部分修改或重新确定 MariaDB/MySQL 设置,以使集群正常运行。例如,Galera 无法使用 MyISAM 或类似的非事务存储引擎,mysqld 也不能绑定到 localhost 的 IP 地址。
Galera Provider Configuration(Galera 提供者配置)"部分配置了提供 WriteSet 复制 API 的 MariaDB 组件。这里指的是 Galera,因为 Galera 是一个 wsrep(WriteSet 复制)提供程序。你需要指定一般参数来配置初始复制环境。这不需要任何定制,但你可以在这里了解更多有关 Galera 配置选项的信息。
Galera 群集配置 "部分定义了群集,通过 IP 地址或可解析域名识别群集成员,并为群集创建名称,以确保成员加入正确的群组。您可以将 wsrep_cluster_name 改为比 test_cluster 更有意义的名称,也可以保持不变,但必须用三台服务器的私有 IP 地址更新 wsrep_cluster_address。
Galera 同步配置 "部分定义了群集如何在成员间通信和同步数据。这部分仅用于节点上线时的状态传输。在初始设置中,我们将使用 rsync,因为它很常见,而且能满足目前的需要。
Galera 节点配置 "部分说明了当前服务器的 IP 地址和名称。这有助于诊断日志中的问题,也有助于以多种方式引用每台服务器。wsrep_node_address 必须与您所在机器的地址一致,但您也可以选择任何名称,以帮助您在日志文件中识别节点。
对群集配置文件满意后,将内容复制到剪贴板,保存并关闭文件。
现在,您已经成功配置了第一个节点,可以在下一节中继续配置其余节点。
步骤 4 - 配置其余节点
在此步骤中,您将配置其余两个节点。在第二个节点上,打开配置文件:
sudo vi /etc/mysql/my.cnf.d/galera.cnf
粘贴从第一个节点复制的配置,然后更新 Galera Node Configuration(Galera 节点配置),使用你要设置的特定节点的 IP 地址或可解析域名。最后,更新节点名称,可将其设置为任何有助于在日志文件中识别节点的名称:
/etc/mysql/my.cnf.d/galera.cnf. . .# Galera Node Configurationwsrep_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
目标:默认
icmp-block-inversion: no
接口:
sources:
services: ssh dhcpv6-client http https
端口
协议:
伪装:否
forward-ports:
source-ports:
icmp-blocks:
rich rules:
如果现在尝试启动群集,就会失败,因为防火墙会阻止节点之间的连接。要解决这个问题,请添加允许 MariaDB 和 Galera 流量通过的规则。
如果现在尝试启动群集,就会失败,因为防火墙会阻止节点之间的连接。要解决这个问题,请添加允许 MariaDB 和 Galera 流量通过的规则。
Galera 可以使用四个端口:
3306 用于 MariaDB 客户端连接和使用 mysqldump 方法的状态快照传输。
4567 用于 Galera 群集复制流量。该端口上的多播复制同时使用 UDP 传输和 TCP。
4568 用于增量状态传输(或 IST),即群集中其他节点接收缺失状态的过程。
4444 用于所有其他状态快照传输,或称 SST,即加入节点从捐献节点获取状态和数据的机制。
在本示例中,你将在进行设置时打开所有四个端口。一旦确认复制工作正常,就关闭任何实际不使用的端口,将流量限制在群集中的服务器上。
使用以下命令打开端口:
sudo firewall-cmd --permanent --zone=public --add-port=3306/tcpsudo firewall-cmd --permanent --zone=public --add-port=4567/tcpsudo firewall-cmd --permanent --zone=public --add-port=4568/tcpsudo firewall-cmd --permanent --zone=public --add-port=4444/tcpsudo firewall-cmd --permanent --zone=public --add-port=4567/udp
使用--zone=public 和--add-port=,firewall-cmd 将向公共流量开放这些端口。--permanent(永久)可确保这些规则持久有效。
注意:根据服务器上运行的其他程序,您可能需要立即限制访问。要进一步了解如何使用 FirewallD,请参阅我们的教程《如何在 CentOS 7 上使用 FirewallD 设置防火墙》。
现在,执行以下命令将每台服务器添加到公共区域,用节点各自的私有 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 默认启用了 SELinux,并限制 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 状态已被设置,在这种情况下不会影响本教程的进程。
在这些命令中,你将使用 SELinux 管理工具 semanage,并使用 -a 标志添加指定的端口并忽略数据库服务器。
接下来,在所有三台服务器上运行以下命令,将 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 ();' 'IST 事件。
现在在所有三台服务器上执行以下命令,创建并启用 SELinux 策略:
sudo grep mysql /var/log/audit/audit.log | sudo audit2allow -M Galera
第一条命令在 audit.log 文件中搜索生成的事件,并将其导入 audit2allow 工具生成的名为 Galera.pp 的模块。输出结果如下:
Output******************** IMPORTANT ***********************
要激活该策略包,请执行
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
最后一行将显示如下内容:
输出。. .
Apr 26 03:34:23 galera-node-01 systemd[1]:停止了 MariaDB 10.4.4 数据库服务器。
关闭所有服务器上的 mariadb 后,就可以继续了。
启动第一个节点
要启动第一个节点,需要使用一个特殊的启动脚本。按照你配置集群的方式,每个上线的节点都会尝试连接其 galera.cnf 文件中指定的至少一个其他节点,以获取初始状态。如果不使用 galera_new_cluster 脚本让 systemd 传递 --wsrep-new-cluster 参数,正常的 systemctl start mariadb 启动就会失败,因为第一个节点没有运行的节点可供连接。
sudo galera_new_cluster
该命令执行成功后不会显示任何输出。脚本执行成功后,节点将注册为群集的一部分,你可以使用以下命令查看:
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
您将看到以下输出,表明群集中有一个节点:
Output+--------------------+-------+
| 变量名
+--------------------+-------+
| 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.设备(类型、数量、颜色)VALUES("滑梯",2,"蓝色");'
在前面的命令中,CREATE DATABASE 语句创建了一个名为 playground 的数据库。CREATE 语句在 playground 数据库中创建了一个名为 equipment 的表,该表有一个名为 id 的自动递增标识符列和其他列。类型列、数量列和颜色列分别用于存储设备的类型、数量和颜色。INSERT 语句插入一个类型为滑梯、数量为 2、颜色为蓝色的条目。
现在表中有一个值。
读写第二个节点
接下来,查看第二个节点,验证复制是否正常:
mysql -u root -p -e 'SELECT * FROM playground.ipment;'。
如果复制正常,您在第一个节点上输入的数据将在第二个节点上可见:
Output+----+-------+-------+-------+
| id | type | quant | color | id | type | quant | color | id | type | quant | color | id
+----+-------+-------+-------+
| 1 | 幻灯片 | 2 | 蓝色 | +++++
+----+-------+-------+-------+
从同一节点,您可以向群集写入数据:
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 | id | type | quant | color | id | type | quant | color | id
+----+-------+-------+--------+
| 1 | 幻灯片 | 2 | 蓝色
| 2 | 摆动 | 10 | 黄色 |
+----+-------+-------+--------+
同样,您可以从这个节点添加另一个值:
mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");'
在第一个节点上读取
回到第一个节点后,您可以验证数据是否到处可用:
mysql -u root -p -e 'SELECT * FROM playground.ipment;'。
您将看到以下输出,表明行在第一个节点上可用。
Output +----+--------+-------+--------+
| id | type | quant | color | id | type | quant | color | id | type | quant | color | id
+----+--------+-------+--------+
| 1 | 幻灯片 | 2 | 蓝色
| 2 | 秋千 | 10 | 黄色
| 3 | 跷跷板 | 3 | 绿色 |
+----+--------+-------+--------+
您已成功验证可以向所有节点写入内容,并且复制正在正常执行。
结论
至此,您已经配置了一个可正常运行的三节点 Galera 测试集群。如果您计划在生产环境中使用 Galera 群集,建议您在开始时至少配置五个节点。
在生产环境中使用之前,您可能需要了解一下其他一些状态快照传输(SST)代理,如 XtraBackup,它可以让您非常快速地设置新节点,而不会对活动节点造成大的干扰。这不会影响实际复制,但在节点初始化时会令人担忧。