MHA高可用切换工具


MHA简介
MHA是一位日本MySQL大牛用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用,在宕机时间内(通常10-30秒),完成故障切换,部署HA,可避免主从不一致问题节约购买服务器的费用,易安装,不改变现有部署。

MHA解决课题


MySQL主从复制架构中,当master发生故障时,有可能会发生一部分(或者全部)的slave未能获取到最新binglog日志,导致slave从库和master数据不一致情况,甚至各salve之间数据也存在偏差
而master能够消除各slave之间数据的差异,最大程度地保证数据一致性,实现真正意义上的高可用1)从宕机崩溃的master保存二进制日志事件(binlog events);2)识别含有最新更新的slave;3)应用差异的中继日志(relay log)到其他的slave;4)提升一个slave为新的master;5)使其他的slave连接新的master进行复制

MHA架构

MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明 在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

MHA特点从master的监控到故障转移全部自动完成,故障也可以选择手动执行

可在秒级单位内实现故障转移

可将任意salve提升为master

安装和卸载MHA不用停止当前正在运行的mysql进程

MHA本身不会增加服务器负担,不会降低性能,不用另外追加服务器

不依赖Storage Engine

不依赖binglog日志文件格式(statement或者row)

具备在多个点上调用外部脚本技能,可以在电源OFF或者IP地址的故障上转移

MHA部署环境:CentOS 6.7_x64 MySQL5.5 多实例(已经实现主从复制)

主库 /data/3306/ 172.16.2.10端口3306 #master
    从库 /data/3307/ 172.16.2.10端口3307 #candicate master 备选主库
从库兼管理 /data/3308/ 172.16.2.10端口3308 #slave

1) 虽然我这里采用的是本地多实例环境,但是还是要配置SSH远程分发密钥,以便MHA管理主机能不用输入密码和其他节点从库通信,如果是不同主机,记得每台都要分发公钥,管理节点自己也要给自己发一次

[root@db02 ~]# ssh-keygen -t rsa
[root@db02 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.2.10


2) 所有节点安装mha的node包

[root@db02 ~]# yum install perl-DBD-MySQL -y #安装依赖包
[root@db02 ~]# rpm -ivh tools/mha4mysql-node-0.54-0.el6.noarch.rpm #mha的node节点包
(下载地址:https://downloads.mariadb.com/files/MHA/mha4mysql-node-0.54-0.el6.noarch.rpm)

3) 管理节点安装manager和相关依赖包

[root@db02 ~]# yum install perl-DBD-MySQL -y
[root@db02 ~]# yum install perl-Config-Tiny -y
[root@db02 ~]# yum install perl-Log-Dispatch -y
[root@db02 ~]# yum install perl-Parallel-ForkManager -y
[root@db02 ~]# yum localinstall tools/mha4mysql-manager-0.55-0.el6.noarch.rpm #localinstall解决循环依赖问题


4) 从库服务器配置 从库服务器配置文件里my.cnf需要添加relay_log_purge=0参数
MySQL数据库主从复制在默认情况下从库的relay logs会在SQL线程执行完毕后被自动删除,但是对于MHA场景下,对于某些滞后从库的恢复依赖于其他的从库relay log,因此需要禁止自动删除功能:

mysql> set global relay_log_purge = 0;

编辑配置文件

my.cnf
 [mysqld]
 relay_log_purge = 0


5) 在所有节点服务器上添加管理账号

mysql> grant all privileges on *.* to mha@'172.16.2.%' identified by 'mha';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

6) 在管理端配置/etc/mha/app1.cnf

[root@db02 ~]# mkdir /etc/mha #新建MHA配置文件夹
[root@db02 ~]# mkdir -p /var/log/mha/app1 #MHA日志管理文件夹
[root@db02 ~]# vim /etc/mha/app1.cnf #管理端配置文件
[server default]
manager_log=/var/log/mha/app1/manager.log #manager日志
manager_workdir=/var/log/mha/app1.log #manager的工作目录
master_binlog_dir=/data/3306/ #master 保存binlog的位置,以便MHA可以找到master的日志
user=mha #设置监控用户root
password=mha #设置监控用户密码
ping_interval=2 #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
repl_password=123456 #设置主从复制用户的密码
repl_user=rep #设置主从复制用户
ssh_user=root #SSH远程连接用户名
[server1]
hostname=172.16.2.10
port=3306
[server2]
candidate_master=1 #设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
check_repl_delay=0 #默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
hostname=172.16.2.10
port=3307
[server3]
hostname=172.16.2.10
port=3308



检查mha manage是否配置成功
1)检查SSH登陆

[root@db02 ~]# masterha_check_ssh --conf=/etc/mha/appl.cnf
...
Sun Jul 10 23:43:10 2016 - [info] All SSH connection tests passed successfully.

2) 检查mysql replication主从复制是否成功

[root@db02 ~]# ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog #所有节点执行
[root@db02 ~]# ln -s /application/mysql/bin/mysql /usr/bin/mysql #所有节点执行
[root@db02 ~]# masterha_check_repl --conf=/etc/mha/appl.cnf
...
Mon Jul 11 00:11:14 2016 - [info] Checking replication health on 172.16.2.10..
Mon Jul 11 00:11:14 2016 - [info]  ok.
Mon Jul 11 00:11:14 2016 - [info] Checking replication health on 172.16.2.10..
Mon Jul 11 00:11:14 2016 - [info]  ok.
Mon Jul 11 00:06:56 2016 - [warning] shutdown_script is not defined.
Mon Jul 11 00:06:56 2016 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.


3) 管理端启动监控和测试启动监控

[root@db02 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
[1] 100414
#--remove_dead_master_conf    该参数代表当发生主从切换后,老的主库的ip将会从配置文件中移除
#--ignore_last_failover   在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover
[root@db02 ~]# masterha_check_status --conf=/etc/mha/app1.cnf #查看主库及节点状态
app1 (pid:100414) is running(0:PING_OK), master:172.16.2.10



这里MHA配置就算结束了,我们来试试停掉主库master,模拟故障
此时3308从库兼管理机器上

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.2.10 
                  Master_User: rep
                  Master_Port: 3306 #显示master是3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000023
          Read_Master_Log_Pos: 3887
               Relay_Log_File: relay-bin.000031
                Relay_Log_Pos: 701
        Relay_Master_Log_File: mysql-bin.000023
             Slave_IO_Running: Yes

我们停掉3306

[root@db02 ~]# mysqladmin -uroot -pli123456 -S /data/3306/mysql.sock shutdown

再来看各同步信息

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.2.10
                  Master_User: rep
                  Master_Port: 3307 #显示主库已经切换为3307了,而且速度非常快
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 3529
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000002

而3307上面,此时已经看不到从库信息了,说明已经被MHA自动变为主库了~

mysql> show slave status\G;
Empty set (0.00 sec)

说明:实际工作中,当真的碰到主库宕机,要秒级切换主库时,这种MHA高可用方案涉及到要变更集群架构中DB的IP操作,会影响很多后端web应用,所有我们最好在连接解析数据库时采用解析主机名的方式,一旦主库宕机,MHA重新选出主库以后,我们可以一键分发hosts解析到所有集群节点,减少更改配置的的麻烦,效率还高!

本文永久更新链接地址

相关内容