基于Galera的MySQL高可用集群

MySQL的高可用方案

我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面:

  • 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中断。
  • 用作备份、只读副本等功能的非主节点的数据应该和主节点的数据实时或者最终保持一致。
  • 当业务发生数据库切换时,切换前后的数据库内容应当一致,不会因为数据缺失或者数据不一致而影响业务。

参考链接

基于多节点可扩展性,部署难易程度,功能复杂度和方案成熟性相关考虑,尝试扩展glaera MySQL cluster方案,并在测试环境中搭建尝试。
预计架构如下: 

搭建准备

环境选用与生产环境一致的CentOS 7.8,MySQL 5.7版本。
测试环境选用3台相同环境服务器尝试集群。

[root@mysql01 ~]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
[root@mysql01 ~]# mysql -V
mysql  Ver 14.14 Distrib 5.7.30, for Linux (x86_64) using  EditLine wrapper

软件包安装

glaera官网下载服务器下载系统对应的软件包,由于MySQL需要安装相对应的插件才能启用相应功能,这里直接从官网下载集成了wsrep插件的安装包,并且下载galera软件包备用。
事实上,下载回来的软件包,在安装之前应该对其进行一致性检验,确保下载过程中不会因为网络等原因造成数据包损坏,也确保下载的文件是官方提供的未经第三方更改。
执行 rpm -Uvh mysql-wsrep-* 以安装所有的软件包,或者使用yum安装以解决依赖
另外,推荐安装xtrabackup用于数据同步引擎,因默认的同步使用rsync方案,有案例报告说在数据发生大规模更新或者新节点加入cluster时,使用rsync是灾难性的。

第一次启动配置

首先在编辑/etc/my.cnf完成数据的配置,运行systemctl start mysqld完成数据库的初始化,待首次初始化启动完成后,查看MySQL生成的临时密码,使用mysql_secure_installation完成数据库的安全安装,过程中需交互,重设root密码和设置关闭远程连接等操作。
初始化完成后,执行systemctl stop mysqld安全关闭MySQL,执行glaera MySQL cluster的配置。

glaera MySQL cluster配置

官方文档说明cluster的相关配置存放于/etc/mysql/conf.d/,但是根据测试发现,该路径配置已经较老,实际只需要在/etc/my.cnf[mysqld]节下添加有关glaera mysql cluster相关配置内容即可。
测试中初步添加如下设置

wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
wsrep_cluster_address=gcomm://172.16.13.81,172.16.13.82,172.16.13.83
binlog_format=row
default_storage_ENGINE=MyISAM
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
# wsrep_sst_method=xtrabackup
wsrep_slave_threads=1
innodb_flush_log_at_trx_commit=0

其中wsrep_cluster_address中包含集群内所有服务器IP数组或者已经启动的单个集群节点IP均可,仅用于当前配置的节点启动时连接的集群节点,连接后可以从任意节点进行数据同步。
更多配置参考:https://galeracluster.com/library/documentation/mysql-wsrep-options.html

配置完成后启动集群

确保配置完成后,使用sudo -u mysql /usr/sbin/mysqld --wsrep-new-cluster启动第一个节点,正常情况下该命令会占用控制台,此时可以另起一个控制台观察启动日志,输出类似于

2020-08-03T10:22:19.543817Z 0 [Note] WSREP: Service thread queue flushed.
2020-08-03T10:22:19.543882Z 0 [Note] WSREP: Assign initial position for certification: 0, protocol version: -1
2020-08-03T10:22:19.543904Z 0 [Note] WSREP: wsrep_sst_grab()
2020-08-03T10:22:19.543908Z 0 [Note] WSREP: Start replication

这样的内容,即表示当前节点的集群已经启动成功,此时可以分发配置到其余各节点,依次启动后续节点,如配置无误,将在启动后自动加入集群。当然,后续节点的配置文件中,需要指定wsrep_cluster_address包含前面已经成功启动的节点。启动后,后续可以在任意节点使用第一节点初始化的账户信息连接数据库,表明数据已经正常同步了。进入数据库后执行show status like 'wsrep_cluster_size';可以查看当前cluster的节点数,并可以使用show status like 'wsrep_%';查看glaera mysql cluster的所有状态信息。
当后续的节点加入cluster后,再cluster中至少有一个节点存活的状态下,其余的节点均可以正常使用systemctl start mysqld命令正常启动节点上的MySQL了。所以此时可以停掉第一个节点手动启动的进程,改用systemd的方式启动服务了。

异常情况下的MySQL启动

如果集群中主节点运行正常,我们只需要正常启动其他节点。所以做关键的一点是在集群全部宕机之后,我们要找到最后一个退出集群,并且数据是最完整的节点。通过启动这个节点,其他节点启动之后与这个节点同步数据才能保证数据库集群的数据不丢失。

找到最后一个停机的节点(seqno 数字最高的节点为下一次启动的主节点,应该首先启动):

# cat /mysql-data/mysql/grastate.dat 
# GALERA saved state
version: 2.1
uuid:8736f68d-0af7-11e7-aba5-9a9e6a4d342c
seqno:   15
safe_to_bootstrap: 0

提示: 如果所有的节点都是seqno的值都为-1,而且我们知道哪一个节点的优先级高,那么我们可以手动指定此节点为引导节点,修改grastate.dat文件的safe_to_bootstrap =1,然后启动此节点。

至于VIP部分

关于对外访问的VIP部分,由于glaera mysql cluster的所有节点都可以作为主节点进行读写,在读写操作数据量不是特别大的场景,可以直接使用keepalived的方案对操作引流到某一台设备进行处理,当节点故障时进行IP漂移实现不停机的故障转移。如果读写场景本身较大,可以使用haproxy进行四层负载均衡,实现更大规模的数据承载,也可以结合keepalived和haproxy实施,彻底消除单点故障,实现MySQL的高可用。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注