MHA高可用配置及故障切换

一、概述

目前 MySQL 已经成为市场主流数据库的一种,考虑到业务的重要性,MySQL 数据库单点问题已成为企业网站架构中最大的隐患,随着技术的发展,MHA 的出现就是解决 MySQL 单点的问题,另外随着企业数据量越来越庞大,数据库的压力又成为企业的另一个瓶颈,MySQL 的多主多从的架构的出现可以减轻 MySQL 的压力。本章将主要介绍 MHA 的搭建和模拟 MySQL 故障自动切换的过程,介绍搭建 MySQL 多主多从的详细过程。

1、什么是MHA

MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。在 MySQL 故障切换过程中,
MHA 能做到在 0~30 秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

2、MHA的组成

该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。MHA Manager 可以单独部署在一*立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。

3、MHA优势

在 MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过 ssh 访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用 MySQL 5.5 的半同步复制,可以大大降低数据丢失的风险。MHA 可以与半同步复制结合起来。如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性。

4、MHA现状

目前 MHA 主要支持一主多从的架构,要搭建 MHA 要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝 TMHA 已经支持一主一从。有兴趣的可以试试。

二、案例环境

MySQL MHA 高可用案例环境

|主机 |操作系统 |

主机 操作系统 主机名/IP地址 角色
服务器 CentOS7.3(64 位) MHA-manager/192.168.11.12 管理节点,安装 manager 组件
服务器 CentOS7.3(64 位) local-1/192.168.11.11 Master 节点,安装 node 组件
服务器 CentOS7.3(64 位) local-2/192.168.11.101 Slave 节点,安装 node 组件
服务器 CentOS7.3(64 位) local-3/192.168.11.102 Slave 节点,安装 node 组件

MHA 架构如图

MHA高可用配置及故障切换

图中MHA可以同时监控并管理多个 MySQL 复制组,本案例只实验其中的一个复制组即可

2. 案例需求

本案例要求通过 MHA 监控 MySQL 数据库在故障时进行自动切换,不影响业务。

3. 案例实现思路

安装 MySQL 数据库
配置 MySQL 一主两从
安装 MHA 软件
配置无密码认证
配置 MySQL MHA 高可用
模拟 master 故障切换

三、案例实施

安装 MySQL 数据库略

3.1 mysql主从复制环境配置

[root@localhost ~]# service mysqld stop 停掉MySQL
[root@localhost ~]# hostnamectl set-hostname local-[1.2.3.4] 先分别修改主机名便于识别
查看时间是否一样,不一样同步阿里云时间 ntpdate time1.aliyun.com
[root@local-1 ~]# ssh-keygen 随便一台生成密钥对
[root@local-1 ~]# cp .ssh/id_rsa.pub .ssh/authorized_keys 复制密钥并改名成公钥可识别名称
[root@local-1 ~]# scp -r .ssh/ 192.168.11.101:/root 递归复制密钥目录到101的root下,也要赋值给102、12
[root@local-1 ~]# echo -e “192.168.11.11 local-1\n192.168.11.101 local-2\n192.168.11.102 local-3\n192.168.11.12 local-4” >> /etc/hosts 做本地域名解析
[root@local-1 ~]# scp /etc/hosts local-4:/etc 域名解析文件复制给11.12,也要复制给其它三台、做了本地域名解析所以可以直接local-1234
[root@local-1 ~]# vim /etc/my.cnf 修改文件1.2.3都要修改出来server_id不一样其它都一样

[mysqld]				#下面内容插入
server_id = 11			#每一个文件的server_id都不能一样
log_bin = mysql-bin
gtid_mode = on
enforce_gtid_consistency = 1 
log_slave_updates = 1 
skip-name-resolve         #禁用dns解析

[root@localhost ~]# service mysqld start 启动所以机的MySQL
mysql> grant replication slave on . to ‘repl’@’%’ identified by ‘123456’;
在11.11和11.101(master和master损坏后接任的slave)上创建 用户
mysql> grant all on . to ‘root’@’%’ identified by ‘123456’;
在11.11和11.101上允许root远程登录
mysql> show master status;
在11.11上查看主
mysql> change master to master_host=‘192.168.11.11’,master_user=‘repl’,master_password=‘123456’,master_log_file=‘mysql-bin.000002’,master_log_pos=640;
在11.101和11.102上user刚创建的、file和pos11.11查看到的
mysql> start slave;
在11.101和11.102上启动
mysql> show slave status\G
在11.101和11.102上查看状态是否两个yes
mysql> set global read_only=1;
在11.101和11.102上设置只读
主从配置完毕

3.2 安装 MHA 软件

所有服务器上都安装 MHA 依赖的环境,首先安装 epel 源。

[root@MHA-manager ~]# yum install -y epel-release
[root@MHA-manager~]# yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN

MHA 软件包对于每个操作系统版本不一样,这里 CentOS7.3 必须选择 0.57 版本,在所有服务器上必须先安装 node组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件,下面都是在local-1 上操作演示安装 node 组件。
[root@local-1 ~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@local-1 ~]# cd mha4mysql-node-0.57
[root@local-1 mha4mysql-node-0.57]# perl Makefile.PL
[root@local-1 mha4mysql-node-0.57]# make && make install

上面有标注的需要在所有机上都做一遍

在 MHA-manager(11.12)上安装 manager 组件
[root@local-4 ~]# tar zxvf mha4MHA-manager-0.57.tar.gz
[root@local-4 ~]# cd mha4MHA-manager-0.57
[root@local-4 mha4MHA-manager-0.57]# perl Makefile.PL
[root@local-4 mha4MHA-manager-0.57]# make && make install

manager 安装后在/usr/local/bin 下面会生成几个工具,主要包括以下几个:

masterha_check_ssh 检查 MHA 的 SSH 配置状况
masterha_check_repl 检查 MySQL 复制状况
masterha_manger 启动 MHA
masterha_check_status 检测当前 MHA 运行状态
masterha_master_monitor 检测 master 是否宕机
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的 server 信息
node 安装后也会在/usr/local/bin 下面会生成几个脚本(这些工具通常由 MHA
Manager 的脚本触发,无需人为操作)主要如下:
save_binary_logs 保存和复制 master 的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的 slave
filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用这个工具)
purge_relay_logs 清除中继日志(不会阻塞 SQL 线程)

配置 MHA

1、在 manager 节点上复制相关脚本文件到/usr/local/bin 目录。

[root@local-4 ~]# cp -a /root/mha4mysql-manager-0.57/samples/scripts/* /usr/local/bin
[root@local-4 ~]# cp /usr/local/bin/master_ip_failover{,.bak}
master_ip_failover #自动切换时 VIP 管理的脚本 master_ip_online_change #在线切换时 vip 的管理
power_manager #故障发生后关闭主机的脚本 send_report #因故障切换后发送报警的脚本
复制上述的自动切换时 VIP 管理的脚本到/usr/local/bin 目录,这里使用脚本管理 VIP,也是推荐的一种方式,生产环境不太建议使用 keepalived。
[root@local-4 ~]# vim /usr/local/bin/master_ip_failover 修改脚本文件

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
    $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
    $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
);
 my $vip = '192.168.11.222/24';
my $key = '1';
my \$ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my \$ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
GetOptions(
    'command=s'          => \\$command,
    'ssh_user=s'         => \\$ssh_user,
    'orig_master_host=s' => \\$orig_master_host,
    'orig_master_ip=s'   => \\$orig_master_ip,
    'orig_master_port=i' => \\$orig_master_port,
    'new_master_host=s'  => \\$new_master_host,
    'new_master_ip=s'    => \\$new_master_ip,
    'new_master_port=i'  => \\$new_master_port,
);
exit &main();
sub main {
    print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
    if ( $command eq "stop" || $command eq "stopssh" ) { 
        my $exit_code = 1;
        eval {
            print "Disabling the VIP on old master: $orig_master_host \n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "start" ) {
        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
        print "Checking the Status of the script.. OK \n";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}
sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
     return 0  unless  ($ssh_user);
    `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
    print
    "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
2. 创建 MHA 软件目录并拷贝配置文件。

[root@local-4 ~]# mkdir /etc/masterha 创建高可用目录
[root@local-4 ~]# cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha
[root@local-4 ~]# vim /etc/masterha/app1.cnf 编辑文件

[server default]
manager_workdir=/var/log/masterha/app1
//设置manager的工作目录
manager_log=/var/log/masterha/app1/manager.log
//设置manager的日志
master_binlog_dir=/data/mysql 
//设置master 保存binlog的位置,以便MHA可以找到master的日志,也就是mysql的数据目录
master_ip_failover_script= /usr/local/bin/master_ip_failover
//设置自动failover时候的切换脚本,也就是上边的哪个脚本
master_ip_online_change_script= /usr/local/bin/master_ip_online_change
//设置手动切换时候的切换脚本
password=123456
//设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
user=root
//设置监控用户root
ping_interval=1
//设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp
//设置远端mysql在发生切换时binlog的保存位置
repl_password=123456
//设置复制用户的密码
repl_user=repl
//设置复制环境中的复制用户名
report_script=/usr/local/bin/send_report
//设置发生切换后发送的报警的脚本
secondary_check_script= /usr/local/bin/masterha_secondary_check -s 192.168.11.101 -s 192.168.11.102
shutdown_script=""
//设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root
//设置ssh的登录用户名
[server1]
hostname=192.168.11.11
port=3306
[server2]
hostname=192.168.11.101
port=3306
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
[server3]
hostname=192.168.11.102
port=3306
3. 测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示。

[root@local-4 ~]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Thu May 17 14:07:29 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
…//省略部分
Thu May 17 14:07:32 2018 - [info] All SSH connection tests passed successfully.

4. 测试 MySQL 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常。如下所示:(有报错检查配置文件没问题就看看11.101的用户有没有允许repl和root远程登录)

[root@local-4 ~]# masterha_check_repl -conf=/etc/masterha/app1.cnf
Thu May 17 16:44:55 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
…//省略部分
MySQL Replication Health is OK.

5. 启动 MHA,下面是具体参数说明:

[root@local-4 ~]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

  • –remove_dead_master_conf 该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。
  • –manger_log 日志存放位置。
  • –ignore_last_failover 在缺省情况下,如果 MHA 检测到连续发生宕机,且两次宕机间隔不足 8 小时的话,则不会进行 Failover,之所以这样限制是为了避免 ping-pong 效应。该参数代表忽略上次 MHA 触发切换产生的文件,默认情况下,MHA 发生切换后会在日志记目录,也就是上面设置的日志 app1.failover.complete 文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为–ignore_last_failover。
    [root@local-4 ~]# cat /var/log/masterha/app1/manager.log 查看有两个ok
    [root@local-4 ~]# tailf /var/log/masterha/app1/manager.log 动态监控
模拟 master 故障
  1. 自动切换
    手动 kill 掉当前的 master
    [root@local-1 ~]# service mysqld stop 在11.11上
    观察 MHA 日志,如果自动切换成功,最后会输出 successfully 字样。
    [root@local-4 ~]# tailf /var/log/masterha/app1/manager.log
    …//省略部分
    Selected 192.168.11.101(192.168.11.101:3306) as a new master.
    192.168.11.101(192.168.11.101:3306): Resetting slave info succeeded.
    Master failover to 192.168.11.101(192.168.11.101:3306) completed successfully
    出现completed successfully自动切换成功

当主库修复后,重新加入群集,Mysql1 作为 Mysql2 的从库(即重新设立主从11.11和11.102当从11.101当主具体过程如上方。注意:需要停止11.101的从服务stop slave然后reset slave否则会报异常)
1)修改/etc/masterha/app1.cnf 文件,将刚刚手动宕机 Mysql1 库作为主库继续提供服务,注意手动切换 VIP 不会漂移。重新检查数据库主从状态是否正常,修改后的 app1.cnf 文件内容如下。
[root@local-4 ~]# vim /etc/masterha/app1.cnf 重新修改文件其它部分一样

secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.11.11 -s 192.168.11.102
[server1]
hostname=192.168.11.11
candidate_master=1
port=3306
[server2]
hostname=192.168.11.101
port=3306
[server3]
hostname=192.168.11.102
port=3306

[root@local-4 ~]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
[root@local-4 ~]# masterha_check_repl -conf=/etc/masterha/app1.cnf 再次检查

2.手动切换
[root@local-2 ~]# service mysqld stop
#停掉11.101模拟故障
[root@local-4 ~]# masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=dead --dead_master_host=192.168.11.101 --dead_master_port=3306 --ignore_last_failover
#回车后按提示yes最后输出successfully

MHA高可用配置及故障切换,自动手动完成

上一篇:MySQL实现MHA高可用


下一篇:Mha-Atlas-MySQL高可用方案实践(二)