如何部署 Galera 数据库集群

2018-11-29 18:00:57 浏览数 (1)

MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方式来避开这个风险。MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,10.0.9版起使用XtraDB来代替MySQL的InnoDB。

在本指南中,我们将配置一个主动 - 主动的MariaDB Galera集群。出于演示目的,我们将配置和测试三个节点,即最小的可配置集群。还没有云服务器的同学可以到腾讯云官网点击产品中的云服务器,进行购买。您也可以到这里免费领取一台腾讯云服务器。

将MariaDB软件包库添加到所有服务器

MariaDB 10.1不包含在默认的Ubuntu软件包库中,因此我们首先将MariaDB项目维护的外部Ubuntu软件包库添加到我们所有的三个服务器中。

注意:MariaDB是一个备受推崇的开源提供商,但并非所有外部软件包库都是可靠的。请务必仅从受信任的来源安装。

首先,我们将使用apt-key命令添加MariaDB软件包库密钥,apt将用于验证包是否可信。

代码语言:javascript复制
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8

一旦我们在数据库中拥有可信密钥,我们就可以添加软件包库。我们需要运行apt-get update才能包含新软件包库中的包清单:

代码语言:javascript复制
sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu xenial main'
sudo apt-get update

注意:您必须在添加软件包库后运行update。否则,您将从Ubuntu软件包安装10.0版本的MariaDB,该软件包不包含Galera软件包。

在所有三台服务器上更新软件包库后,我们就可以安装MariaDB了。有关MariaDB的一点需要注意的是,它是MySQL的替代品,所以在许多配置文件和启动脚本中,你会看到mysql而不是mariadb。为了保持一致性,我们在后续配置的时候使用mysql

在所有服务器上安装MariaDB

从版本10.1开始,MariaDB Server和MariaDB Galera Server软件包捆绑在一起,因此安装mariadb-server将自动安装Galera和几个依赖项:

代码语言:javascript复制
sudo apt-get install mariadb-server

在安装过程中,系统会要求您为MariaDB管理用户设置密码。我们会将第一个集群节点的复制到其他节点,当复制后,MariaDB root密码将被第一个节点的密码覆盖。

我们应该满足了开始配置集群所需的所有条件,但由于我们将在后面的步骤中依赖rsync,所以我们需要确保已经安装了它。

代码语言:javascript复制
sudo apt-get install rsync

这将确认您是否安装了最新版本rsync

一旦我们在三台服务器上安装了MariaDB,我们就可以开始配置了。

配置第一个节点

集群中的每个节点都需要相同的配置。因此,我们将在第一台机器上执行所有配置,然后将其复制到其他节点。

默认情况下,MariaDB会检查/etc/mysql/conf.d目录获取以.cnf结束的配置设置。我们将在此目录中创建一个包含所有特定于集群的指令的文件:

代码语言:javascript复制
sudo nano /etc/mysql/conf.d/galera.cnf

将以下配置复制并粘贴到文件中。您需要更改红色突出显示的设置。我们将在下面解释每个部分的含义。

代码语言:javascript复制
[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_ip,second_ip,third_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 Cluster不能与MyISAM或类似的非事务性存储引擎一起使用,mysqld也不能绑定到localhost的IP地址。您可以在Galera Cluster系统配置页面上更详细了解这些设置。
  • “Galera Provider Configuration”部分配置提供WriteSet复制API的MariaDB组件。在我们的例子中,这意味着Galera,因为Galera是一个wsrep提供程序。我们指定用于配置初始复制环境的常规参数。
  • “Galera集群配置”部分定义集群,通过IP地址或域名标识集群成员,并为集群创建名称以确保成员加入正确的群组。您可以将wsrep_cluster_name更改为更有意义的内容,但必须使用三台服务器的地址更新wsrep_cluster_address。如果您的服务器具有专用IP地址,请在此处使用它们。
  • “Galera同步配置”部分定义了集群如何在成员之间进行通信和同步数据。这仅用于节点联机时发生的状态转移。对于我们的初始设置,我们使用rsync,因为它通常可以满足我们现在需要的。
  • “Galera节点配置”部分阐明了IP地址和当前服务器的名称。在尝试诊断日志中的问题以及以多种方式引用每个服务器时,这很有用。wsrep_node_address必须和你机器的地址相匹配,但你可以选择你想要的任何名称,以帮助您识别在日志文件中的节点。

如果对集群配置文件感到满意,请将内容复制到剪贴板,保存并关闭文件。

配置剩余节点

在每个剩余节点上,打开配置文件:

代码语言:javascript复制
sudo nano /etc/mysql/conf.d/galera.cnf

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

代码语言:javascript复制
. . .
# Galera Node Configuration
wsrep_node_address="this_node_ip"
wsrep_node_name="this_node_name"
. . .

保存并退出每台服务器上的文件。我们已经准备好调出集群,但在我们开始之前,我们需要确保端口是开放的。

在每个服务器上打开防火墙

在每台服务器上,让我们检查防火墙的状态,如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置:

代码语言:javascript复制
sudo ufw status
Status: active
​
To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

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

Galera需要使用四个端口:

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

在我们的示例中,我们将在设置时打开所有四个端口。一旦我们确认复制正常,我们会关闭我们实际上没有使用的端口,并将流量限制在集群中的服务器上。

使用以下命令打开端口:

代码语言:javascript复制
sudo ufw allow 3306,4567,4568,4444/tcp
sudo ufw allow 4567/udp

启动集群

首先,我们需要停止正在运行的MariaDB服务,以便我们的集群可以联机。

在所有三台服务器上停止MariaDB:

在所有三台服务器上使用以下命令来停止mysql,以便我们可以将它们备份到集群中:

代码语言:javascript复制
sudo systemctl stop mysql

systemctl不显示服务命令的结果,为了确保我们成功,我们将使用以下命令:

代码语言:javascript复制
sudo systemctl status mysql

如果最后一行看起来如下所示,命令成功。

代码语言:javascript复制
 . . . 
Aug 19 02:55:15 galera-01 systemd[1]: Stopped MariaDB database server.

一旦关闭了mysql所有服务器,我们就可以继续了。

打开第一个节点:

要调出第一个节点,我们需要使用特殊的启动脚本。每个联机的节点都尝试连接到其galera.cnf文件中指定的至少一个其他节点以获取其初始状态。如果不使用galera_new_cluster允许systemd传递--wsrep-new-cluster参数的脚本,则systemctl start mysql会失败,因为没有节点为第一个节点连接而运行。

代码语言:javascript复制
sudo galera_new_cluster

当此脚本成功时,该节点将注册为集群的一部分,我们可以使用以下命令查看它:

代码语言:javascript复制
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
 -------------------- ------- 
| Variable_name      | Value |
 -------------------- ------- 
| wsrep_cluster_size | 1     |
 -------------------- ------- 

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

打开第二个节点:

启动mysql

代码语言:javascript复制
sudo systemctl start mysql

随着每个节点上线,我们应该看到我们的集群大小增加:

代码语言:javascript复制
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
 -------------------- ------- 
| Variable_name      | Value |
 -------------------- ------- 
| wsrep_cluster_size | 2     |
 -------------------- ------- 

打开第三个节点:

启动mysql

代码语言:javascript复制
sudo systemctl start mysql 

如果一切正常,则集群大小应变成了3:

代码语言:javascript复制
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
 -------------------- ------- 
| Variable_name      | Value |
 -------------------- ------- 
| wsrep_cluster_size | 3     |
 -------------------- ------- 

此时,整个集群应该在线并可以进行通信。然而,在我们测试复制之前,还有一个配置细节需要注意。

配置Debian维护用户

目前,Ubuntu和Debian的MariaDB服务器作为特殊维护用户进行日常维护。当我们安装MariaDB时,该用户的凭据随机生成,存储在/etc/mysql/debian.cnfMariaDBmysql数据库中。

一旦我们启动了集群,第一个节点的密码就会被复制到其他节点,因此debian.cnf值不再与数据库中的密码匹配。这意味着使用维护帐户的内容都将尝试使用配置文件中的密码连接到数据库,并且除了第一个节点之外的所有帐户都将失败。

为了解决这个问题,我们将第一个节点的debian.cnf复制到其余节点。

从第一个节点复制:

使用文本编辑器打开debian.cnf文件:

代码语言:javascript复制
sudo nano /etc/mysql/debian.cnf

该文件应该类似于:

代码语言:javascript复制
[client]
host     = localhost
user     = debian-sys-maint
password = 03P8rdlknkXr1upf
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host     = localhost
user     = debian-sys-maint
password = 03P8rdlknkXr1upf
socket   = /var/run/mysqld/mysqld.sock
basedir  = /usr

将信息复制到剪贴板中。

更新第二个节点:

在第二个节点上,打开相同的文件:

代码语言:javascript复制
sudo nano /etc/mysql/debian.cnf

尽管文件顶部有“请勿修改!”的警告,但我们需要对集群进行更改才能正常工作。您可以放心地删除当前信息并粘贴第一个节点配置中的内容。保存并关闭文件。

更新第三个节点:

在第三个节点上,打开同一个文件:

代码语言:javascript复制
sudo nano /etc/mysql/debian.cnf

删除当前信息并粘贴第一个节点配置中的内容。保存并关闭文件。虽然文件不匹配不会影响我们测试复制,但最好尽早处理以避免以后出现故障。

注意:完成后,您可以通过本地密码来测试维护帐户是否能够连接debian.conf,如下所示: sudo cat /etc/mysql/debian.cnf 从输出中复制密码。然后连接到mysql: mysql -u debian-sys-maint -p 在提示符下,提供您复制的密码。如果没有链接,请验证文件中的密码是否与第一个节点相同,然后在下面替换: update mysql.user set password=PASSWORD('password_from_debian.cnf') where User='debian-sys-maint'; 测试剩余节点。

测试复制

我们的集群可以执行从任何节点到任何其他节点的复制,称为主动 - 主动主 - 主复制。让我们测试复制是否按预期工作。

写入第一个节点:

我们首先在第一个节点上进行数据库更改。以下命令将创建一个名为playground的数据库,并在其中调用一个equipment表。

代码语言:javascript复制
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");'

我们现在在表中有一个值。

在第二个节点上读写:

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

代码语言:javascript复制
mysql -u root -p -e 'SELECT * FROM playground.equipment;'

如果复制正常,我们在第一个节点上输入的数据将在第二个节点上显示:

代码语言:javascript复制
 ---- ------- ------- ------- 
| id | type  | quant | color |
 ---- ------- ------- ------- 
|  1 | slide |     2 | blue  |
 ---- ------- ------- ------- 

从这个节点,我们可以将数据写入集群:

代码语言:javascript复制
mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");'

在第三个节点上读写:

在第三个节点上,我们可以通过再次查询来读取所有这些数据:

代码语言:javascript复制
mysql -u root -p -e 'SELECT * FROM playground.equipment;'
    ---- ------- ------- -------- 
   | id | type  | quant | color  |
    ---- ------- ------- -------- 
   |  1 | slide |     2 | blue   |
   |  2 | swing |    10 | yellow |
    ---- ------- ------- -------- 

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

代码语言:javascript复制
mysql -u root -p -e 'INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");'

在第一个节点上查看:

回到第一个节点,我们可以验证我们的数据在任何地方都可用:

代码语言:javascript复制
mysql -u root -p -e 'SELECT * FROM playground.equipment;'
    ---- -------- ------- -------- 
   | id | type   | quant | color  |
    ---- -------- ------- -------- 
   |  1 | slide  |     2 | blue   |
   |  2 | swing  |    10 | yellow |
   |  3 | seesaw |     3 | green  |
    ---- -------- ------- -------- 

我们已经测试我们可以写入所有节点,并且可以正确执行复制。

结论

此时,您应该拥有了一个有效的三节点Galera测试集群。如果您计划在生产环境中使用Galera集群,建议您从不少于五个节点开始。在生产使用之前,您可能需要查看一些快照传输(sst)代理,例如“xtrabackup”,它允许您非常快速地设置新节点,而不会对您的活动节点造成大的中断。不会影响实际复制,您可以在初始化节点时考虑配置一下。

最后,如果您的集群在公网上,您还需要设置SSL以保护数据在服务器之间移动时的数据。我推荐您使用腾讯云SSL证书服务。自行部署集群难免会遇到各种问题,我推荐您使用腾讯分布式服务框架进行集群管理,腾讯分布式框架,提供多维度应用、服务、机器的监控数据,助力服务性能优化;拥抱 Spring Cloud 开源社区。 配合腾讯云云关系型数据库,可将您从耗时的数据库管理任务中解放出来,让您有更多时间专注于您的应用和业务。

0 人点赞