vlambda博客
学习文章列表

基于半同步复制的MHA高可用MySql集群架构搭建实战

一、什么是MHA架构

1. 简介

MHA(Master High Availability)是一套比较成熟的 MySQL 高可用方案,也是一款优秀的故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。MHA还支持在线快速将Master切换到其他主机,通常只需0.5-2秒。

目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器。

2. MHA组成部分

MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。

  • MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。负责检测master是否宕机、控制故障转移、检查MySQL复制状况等。

  • MHA Node运行在每台MySQL服务器上,不管是Master角色,还是Slave角色,都称为Node,是被监控管理的对象节点,负责保存和复制master的二进制日志、识别差异的中继日志事件并将其差异的事件应用于其他的slave、清除中继日志。

MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master,整个故障转移过程对应用程序完全透明。

MHA架构图如下


3.MHA故障处理机制:
  • 把宕机master的binlog保存下来

  • 根据binlog位置点找到最新的slave

  • 用最新slave的relay log修复其它slave

  • 将保存下来的binlog在最新的slave上恢复

  • 将最新的slave提升为master

  • 将其它slave重新指向新提升的master,并开启主从复制

4. MHA优点:
  • 自动故障转移快

  • 主库崩溃不存在数据一致性问题

  • 性能优秀,支持半同步复制和异步复制

  • 一个Manager监控节点可以监控多个集群

二、MHA架构搭建  

1. 集群环境(4台主机,1主、2从、1 MHA)
机器名称 IP 用途 备注
master 192.168.2.201 主数据库 centos7 已安装mysql5.7版本
slave1 192.168.2.202 从数据库 centos7已安装mysql5.7版本
slave2 192.168.2.203 从数据库 centos7 已安装mysql5.7版本
manager 192.168.2.204 MHA manager centos7 初始环境,未安装任何软件
2. MySql主从复制集群搭建

2.1 配置主数据库

  • 修改配置文件并增加如下配置

[root@localhost ~]# vim /etc/my.cnf

# 开启二进制文件日志
log_bin=mysql-bin
# 服务id 不同主机不能重复
server-id=1
#可选 每次执行写日志操作都与磁盘进行同步
sync-binlog=1
#可选 不进行数据同步的数据库
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# 可选 需要进行同步的数据库
binlog-do-db=database

基于半同步复制的MHA高可用MySql集群架构搭建实战

  • 重启数据库服务

[root@localhost ~]# systemctl restart mysqld
  • 登录mysql数据库并进行授权

[root@localhost ~]# mysql -uroot -p

mysql> use mysql;

mysql>grant replication slave on *.* to 'root'@'%' identified by '123456';
mysql>grant all privileges on *.* to 'root'@'%' identified by '123456';

注意:

若授权时有报错

Your password does not satisfy the current policy requirements

此时为密码 不符合安全策略, 我们需要调整mysql的密码安全级别

查看密码策略

mysql>  show variables like 'validate_password%';

+--------------------------------------+-------+
| Variable_name                       | Value |
+--------------------------------------+-------+
| validate_password_check_user_name   | OFF   |
| validate_password_dictionary_file   |       |
| validate_password_length             | 8     |
| validate_password_mixed_case_count   | 1     |
| validate_password_number_count       | 1     |
| validate_password_policy             |MEDIUM |
| validate_password_special_char_count | 1     |
+--------------------------------------+-------+

可以看到此时mysql的密码策略较高, 我们需要调低

mysql> set global validate_password_policy=0;
mysql> set global validate_password_length=1;

然后在进行授权操作就可以了

  • 授权成功后, 我们查看下master状态

mysql> show master status

基于半同步复制的MHA高可用MySql集群架构搭建实战

注意图中红框中的内容, 配置从节点同步数据时需要用到此内容

2.2 从数据库配置

  • 同样编辑配置文件添加如下配置

# 注意与主库和其他从库区别
server-id=2
# 中继日志名称 不指定为默认值
relay_log=mysql-relay-bin
#只读
read_only=1
  • 重启后查看从库状态

mysql>show slave status;
Empty set (0.00 sec) # 表明为第一次设置从库 若有信息 需要 drop slave
  • 指定需要同步的主库信息

# 注意切换到mysql数据库
mysql>use mysql;

mysql>change master to master_host='192.168.2.201',master_port=3306,master_user='root',master_password='123456',master_log_file='mysql-bin.00002',master_log_pos=869;

master_host #主库host地址
master_port #主库端口
master_user #登录主库的用户名
master_password #密码
master_log_file #需要同步的主库日志文件, 此处为查看主库状态时file 列对应的值
master_log_pos #同步起始位置 此处为查看主库状态时position 列对应的值
  • 启动从库

mysql>start slave;
3. 开启半同步复制功能

半同步复制需要 semi 模块的支持, 我们当前安装的mysql5.7版本未安装semi插件, 所以需要我们手动安装semi模块

  • 先查看是否支持动态插件安装

mysql>select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                   |
+------------------------+
1 row in set (0.00 sec)
  • 安装semi插件 并命名"semisync_master.so" (同 maradb)

# 主库需要安装master模块
mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so';

# 从库安装slave模块
mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
  • 修改semi 参数

# 查看semi相关参数
mysql>show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value     |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled             | OFF       |
| rpl_semi_sync_master_timeout             | 10000     |
| rpl_semi_sync_master_trace_level         | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1         |
| rpl_semi_sync_master_wait_no_slave       | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.02 sec)

主库参数修改

# 开启semi插件
mysql>set global rpl_semi_sync_master_enabled=1;
# 设置超时时间
mysql>set global rpl_semi_sync_master_timeout=1000;

从库参数修改

# 开启semi插件
mysql>set global rpl_semi_sync_slave_enabled=1;

重启slave
mysql>stop slave;
mysql>start slave;
4. 基于主从复制搭建MHA高可用集群

4.1 修改数据库配置

MHA slave节点都需要开启二进制日志和中继日志, 且需要关闭relay log的自动清除功能, 同时指定需要同步的数据库配置必须和主库一致, 所以需要修改slave的配置文件, 增加如下配置信息

# 开启二进制日志
log-bin=mysql-bin
# 是否自动清空不再需要中继日志
relay_log_purge=0
# 指定忽略的数据库, 与master配置一致
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

MHA在发生切换的过程中,从库的恢复过程中依赖于relay log的相关信息,所以这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。在默认情况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。但是在MHA环境中,这些中继日志在恢复其他从服务器时可能会被用到,因此需要禁用中继日志的自动删除功能。定期清除中继日志需要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件需要一定的时间,会导致严重的复制延时。为了避免复制延时,需要暂时为中继日志创建硬链接,因为在Linux系统中通过硬链接删除大文件速度会很快。

4.2  开启各个主机间 的 ssh免密码登录

MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。简单起见,可在Manager节点生成密钥对儿,并设置其可远程连接本地主机后, 将私钥文件及authorized_keys文件复制给余下的所有节点即可。

注意:下面操作在所有节点上操作

[root@localhost ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): // 回车
Enter passphrase (empty for no passphrase): // 回车
Enter same passphrase again: // 回车

基于半同步复制的MHA高可用MySql集群架构搭建实战

当前主机为: 192.168.2.204

[root@localhost ~]# ssh-copy-id 192.168.2.201
[root@localhost ~]# ssh-copy-id 192.168.2.203
[root@localhost ~]# ssh-copy-id 192.168.2.204

基于半同步复制的MHA高可用MySql集群架构搭建实战

当四台机器都进行了上述操作以后,我们可以在 manager 机器上看到如下文件:

[root@localhost ~]# cd .ssh/
[root@localhost .ssh]# ls
authorized_keys id_rsa id_rsa.pub known_hosts
[root@localhost .ssh]# cat authorized_keys

基于半同步复制的MHA高可用MySql集群架构搭建实战

此时,我们也可以在机器上实验一下,看看 ssh 是否还需要输入密码。本步骤完成。

4.3 MHA 安装

在本步骤中, Manager节点需要另外多安装一个包。具体需要安装的内容如下:

四个节点都需安装:mha4mysql-node-0.58-0.el7.centos.noarch.rpmManager 节点另需要安装:mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

将下载好的rmp安装包上传到各个主机, 执行如下命令进行安装

先切换到rmp所在目录, 我上传时就直接上传到了root目录下了

[root@localhost ~]# mha4mysql-node-0.58-0.el7.centos.noarch.rpm

# manager节点需要单独安装
[root@localhost ~]# mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

4.4 定义 MHA 管理配置文件

Manager 节点需要为每个监控的 master/slave 集群提供一个专用的配置文件,而所有的 master/slave 集群也可共享全局配置。全局配置文件默认为/etc/masterha_default.cnf,其为可选配置。如果仅监控一组 master/slave 集群,也可直接通过 application 的配置来提供各服务器的默认配置信息。而每个 application 的配置文件路径为自定义。

创建mha配置文件并添加如下配置内容

文件路径及名称可以自己定义, 我的配置文件及路径是: /etc/mha_master/mha.cnf

# 通用配置 适用于server1,2,3 三个server的配置
[server default]
# 配置mha管理用户的用户名和密码
# 设置监控用户root
user=root
# 设置MySQL中root用户的密码,这个密码是前文中创建监控用户的那个密码
password=123456
#mha manager的工作路径
manager_workdir=/data/mha_manager/app1
#mha manager日志存放路径
manager_log=/data/mha_manager/app1/log/manager.log
# 远程主机工作目录 即 设置远端mysql在发生切换时binlog的保存位置
remote_workdir=/data/mha_manager/app1
# 设置ssh的登录用户名
ssh_user=root
# slave数据库用户名及密码
repl_user=root
repl_password=123456
# 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
ping_interval=1

[server1]
hostname=192.168.2.201
port=3306
# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库。
candidate_master=1
[server2]
hostname=192.168.2.202
port=3306
candidate_master=1
[server3]
hostname=192.168.2.203
port=3306
candidate_master=1

# no_master=1 此配置可以指定server3永远不能称为主节点
[root@localhost log]#

4.5 SSH 有效性验证

[root@localhost ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf

若未能测试成功,

基于半同步复制的MHA高可用MySql集群架构搭建实战

再重新配置一遍ssh认证即可

基于半同步复制的MHA高可用MySql集群架构搭建实战

此时表明ssh连通性没有问题

4.6 集群复制的有效性验证

[root@localhost ~]# masterha_check_repl --conf=/etc/mha_master/mha.cnf

踩的坑

  1. 配置的mha管理用户必须是经过授权的

  2. slave节点需要开启二进制日志

  3. slave节点需要开启中继日志

  4. slave节点库同步配置信息要与master节点一致

否则在此步

会报错!

基于半同步复制的MHA高可用MySql集群架构搭建实战

会报错!

基于半同步复制的MHA高可用MySql集群架构搭建实战

会报错!

基于半同步复制的MHA高可用MySql集群架构搭建实战

解决了一系列问题后, 终于看到我想看到了的

基于半同步复制的MHA高可用MySql集群架构搭建实战

基于半同步复制的MHA高可用MySql集群架构搭建实战

注意:验证成功的话会自动识别出所有服务器和主从状况!!!

4.7 启动 manager

[root@localhost ~]# masterha_manager --conf=/etc/mha_master/mha.cnf

基于半同步复制的MHA高可用MySql集群架构搭建实战

注意:在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用&在程序结尾来让程序自动运行。比如我们要运行mysql在后台:/usr/local/mysql/bin/mysqld_safe –user=mysql&。可是有很多程序并不想mysqld一样,这样我们就需要nohup命令,

nohup masterha_manager –conf=/etc/mha_master/mha.cnf > /data/mha_manager/app1/mha_manager.log &1 &

4.8 模拟故障,检测状态转移

我们停掉master节点后, 来看一下manager日志

cat /data/mha_manager/app1/log/manager.log  #此路径是我在mha.cnf中配置的manager日志存放路径

可以看到, mha已经识别到master已经挂掉, 并且成功的将主节点从192.168.2.201 转移到了 192.168.2.202上。

4.9 故障恢复

停掉的原master节点, 再次上线后也会作为slave节点, 若要重新设置为master节点需要进行一下几个步骤

  1. 在mha manager节点上删除app1.failover.complete文件

    cd /data/mha_manager/app1       //此目录为配置文件mha.cnf我设置的mha工作目录
    rm -f app1.failover.complete // 删除此文件
  2. 启动原master主节点mysql服务

    此时若验证集群复制的有效性会报错

  3. 查看现在的slave1上的信息

    mysql> show master status\G
    *************************** 1. row ***************************
    File: mysql-bin.000010
    Position: 120
    Binlog_Do_DB:
    Binlog_Ignore_DB:
    Executed_Gtid_Set:
    1 row in set (0.00 sec)
  4. 配置原master节点mysql为新的slave,并启动同步进程

    mysql> change master to master_host='192.168.2.202',
    master_user='root',
    master_password='123456',
    master_log_file='mysql-bin.000010',
    master_log_pos=120;

    mysql> start slave;

    注意:按如上步骤操作后,此时201节点作为slaver已加入到集群中,但是宕机这段时间202、203中新产生的数据在201中没有,所以还需要先从主节点备份导入最新的数据再启动同步

  5. 启动MHA

    nohup masterha_manager –conf=/etc/mha_master/mha.cnf > /data/mha_manager/app1/mha_manager.log &1 &

同样的道理,以上步骤配置无问题的话停止当前master的MySQL进程,MHA可直接切换master至原节点

切换过程中需要关注的几个问题
  • 切换过程会自动把read_only关闭

  • 切换之后需要删除手工删除/masterha/app1/app1.failover.complete,才能进行第二次测试

  • 一旦发生切换管理进程将会退出,无法进行再次测试,需将故障数据库加入到MHA环境中来

  • 原主节点重新加入到MHA时只能设置为slave,在

change master to master_host='192.168.56.122',
master_user='repl',
master_password='repl',
master_log_file='mysql-bin.000010',
master_log_pos=120;

之前需要先 reset slave

  • 注意:二级从服务器需要将log_slave_updates打开

  • 通过设置no_master=1可以让某一个节点永远不成为新的主节点