MHA高可用 MHA+Keepalive

时间:2021-01-11 15:31:44

MHA高可用

MHA简介

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

MHA功能

MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;
在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的 replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量
另外,安装简单,无性能损耗,以及不需要修改现 有的复制部署也是它的优势之处。
MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中 (通过将从库提升为主库),大概0.5-2秒内即可完成。
MHA Manager可以单独部署在一*立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

MHA工作原理

工作原理说明:
1、保存master上的所有binlog事件
2、找到含有最新binlog位置点的slave
3、通过中继日志将数据恢复到其他的slave
4、将包含最新binlog位置点的slave提升为master
5、将其他从库slave指向新的master原slave01 并开启主从复制
6、将保存下来的binlog恢复到新的master上

MHA工具介绍

MHA软件由两部分组成,Manager工具包和Node工具包

masterha_check_ssh               #检査 MHA 的 ssh-key
masterha_check_repl              #检査主从复制情况
masterha_manger                  #启动MHA
masterha_check_status            #检测MHA的运行状态^
masterha_mast er_monitor         #检测master是否宕机
masterha_mast er_switch          #手动故障转移—
masterha_conf_host               #手动添加server倍息
masterha_secondary_check         #建立TCP连接从远程服务器v
masterha_stop                    #停止MHA 

Node工具包主要包括以下几个工具:

save_binary_1ogs                 #保存宕机的master的binlog
apply_diff_relay_logs            #识别relay log的差异
filter_mysqlbinlog               #防止回滚事件一MHA已不再使用这个工具
purge_relay_logs                 #清除中继曰志一不会阻塞SQL线程 

MHA的优点

1、自动故障转移
2、主库崩溃不存在数据不一致的情况
3、不需要对当前的mysql环境做重大修改
4、不需要添加额外的服务器
5、性能优秀,可以工作再半同步和异步复制框架
6、只要replication支持的存储引擎mha都支持

MHA部署

本次部署包括 mysql主从同步+MHA高可用+keepalived
mha版本0.56
数据库5.7

机器名 IP地址 功能划分
db01 172.16.1.51 主 keepalived node
db02 172.16.1.52 从 keepalived node
db03 172.16.1.53 从 manager node

基础环境部署

基础内容

关闭防火墙和selinux

systemctl stop firewalld && setenforce 0

下载数据库
安装mysql, 默认5.7版本, 使用本地yum源下载

yum install mysql-community-server -y

修改配置文件

修改配置文件/etc/my.cnf server-id 以IP最后一段命名
db01的内容

[root@db01 ~]# vi /etc/my.cnf   #使用vi打开
[mysqld]
server-id=51
log-bin = master-log
relay-log = relay-log
skip_name_resolve  

db02的内容

[root@db02 ~]# vi /etc/my.cnf
server-id=52
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1

db03的内容

[root@db03 ~]# vi /etc/my.cnf
[mysqld]
server-id = 53
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1

启动数据库, 并加入开机自启动

systemctl start mysqld && systemctl enable mysqld

修改密码及导入数据
修改密码

登陆mysql数据库  [password中填写上一步过滤的密码]
mysql -uroot -p$(awk '/temporary password/{print $NF}' /var/log/mysqld.log)
修改数据库密码
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Bgx123.com';
mysql> exit

导入原先的数据(三台机器都要操作)

mysql -uroot -pBgx123.com < /tmp/db-all.sql  #导入原有的数据库即可

然后重启mysql

systemctl restart mysqld

增加用户

db01主库的操作

[root@db01 ~]# mysql -uroot -pBgx123.com
mysql> grant all on *.* to 'all'@'%' identified by 'Bgx123.com';   #这个是配置远程连接规则
mysql> grant replication slave, replication client  on *.*
to 'rep'@'172.16.1.%' identified by 'Rep123.com';  #授权, 允许能够远程连接的主机(replicaiton)
mysql> flush privileges;

在 master 上进行授权
在所有 Mysql进行授权
拥有管理权限的用户可在本地网络中有其他节点上远程访问。 mha为manager管理用户

mysql> grant all on *.* to 'mha'@'172.16.%.%' identified by 'Bgx123.com';  #所有数据库都要进行授权
mysql> flush privileges;
#mysql 新设置用户或更改密码后需用flush privileges刷新MySQL的系统权限相关表,否则会出现拒绝访问

安装MHA软件

(在三个节点上都装mha的node软件)
在db03(manager监控端)安装manager

[root@db01 ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db02 ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db03 ~]# ll
-rw-r--r--  1 root root 87119 Oct 24 20:11 mha4mysql-manager-0.56-0.el6.noarch.rpm
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm

首先要确保yum源有base源和epel源而且可以上网
因为mha安装会安装依赖

[root@db02 ~]# ll /etc/yum.repos.d/
-rw-r--r-- 1 root root 2523 Sep  4 17:06 CentOS-Base.repo
-rw-r--r-- 1 root root  664 Sep  4 17:06 epel.repo

然后直接使用yum install 安装
db03 manager node都要安装 其他两台只安装node

 [root@db01 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y
[root@db02 ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db03 ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
[root@db03 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm

配置manager

mha配置文件内容

[root@db03 ~]# mkdir /etc/mha_master/
[root@db03 ~]# cat /etc/mha_master/mha.cnf
[server default]
user=mha
password=Bgx123.com
manager_workdir=/etc/mha_master/app1
manager_log=/etc/mha_master/manager.log
remote_workdir=/mydata/mha_master/app1
ssh_user=root
repl_user=rep
repl_password=Rep123.com
ping_interval=1
[server1]
hostname=172.16.1.51
port=3306
candidate_master=1
[server2]
hostname=172.16.1.52
port=3306
candidate_master=1
#[server3]
#hostname=172.16.1.53
#port=3306
#candidate_master=1

配置三台机器的ssh互信(三台都要操作)在配置MHA会要求三台数据库无密码通信

ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.51
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.52
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.1.31
#测试是否成功
ssh 172.16.1.52   不用输入密码就证明成功

指向Master 只在db02 db03操作
在两个salve节点(从库)上执行,只读限制(防止意外被写数据,很重要)

mysql> set global read_only=1;
mysql> change master to
    -> master_host='172.16.1.51',
    -> master_user='rep',
    -> master_password='Rep123.com';
mysql> start slave;
mysql> show slave status\G; #查看slave IO和slave sql是否都正常 Yes就是正常的
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

测试配置

测试连通性

[root@db03 ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf  #最后一行如下图即为成功

MHA高可用 MHA+Keepalive

确认上一步连通性没问题后开始下一步检查
检查管理的MySQL复制集群的连接配置参数是否OK

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

MHA高可用 MHA+Keepalive

底部显示OK即为正常

配置VIP漂移

配置Keepalived

使用keepalived做VIP转移
keepalived只在 db01 db02上安装

[root@db01 ~]# yum install keepalived -y
[root@db02 ~]# yum install keepalived -y

keepalived db01的配置文件内容

[root@db01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id db01
}
vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
}
    virtual_ipaddress {
        172.16.1.66/24 dev eth1
    }
}

启动keepalived

systemctl start keepalived.service

keepalived db02的配置文件内容

[root@db02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id db02
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.16.1.66/24 dev eth1
    }
}

配置完不要忘记启动

systemctl start keepalived.service

配置脚本内容

写入脚本内容(我们使用的yum安装 没有自带的脚本 所以自己写)见文件包内

[root@db03 ~]# cat /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 = '172.16.1.66';
my $ssh_start_vip = "systemctl start keepalived";
my $ssh_stop_vip = "systemctl stop keepalived";
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 \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
    `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";
}

给脚本增加执行权限不然会报错

[root@db03 ~]# chmod +x /usr/local/bin/master_ip_failover

在db03的配置文件内加入一行(在原有内容的基础上增加)

[root@db03 ~]# vim /etc/mha_master/mha.cnf
master_ip_failover_script= /usr/local/bin/master_ip_failover

测试连通性

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

测试配置

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

启动mha (在db03上执行)

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &
[1] 13530  #这个号码每次都会不一样
[root@db03 ~]# masterha_check_status -conf=/etc/mha_master/mha.cnf
mha (pid:13530) is running(0:PING_OK), master:172.16.1.51

上面的信息中“mha (pid:13530) is running(0:PING_OK)”表示MHA服务运行OK,否则, 则会显示为类似“mha is stopped(1:NOT_RUNNING).”

如果,我们想要停止 MHA ,则需要使用 stop 命令:
[root@manager ~]# masterha_stop -conf=/etc/mha_master/mha.cnf

测试 MHA 故障转移

先在db03打开日志

[root@db03 ~]# tail -f /etc/mha_master/manager.log

主库 db01 关闭 mariadb 服务,模拟主节点数据崩溃

[root@db01 ~]# systemctl stop mysqld

转移后的恢复

重新启动主库后
db01的操作(不要忘记重启)

[root@db01 ~]# systemctl start mysqld
[root@db01 ~]# systemctl start keepalived.service 

在从库上执行以下命令(重新设置从库)

mysql> stop slave;
mysql> reset slave;
mysql> CHANGE MASTER TO
    MASTER_HOST=' 172.16.1.51',
    MASTER_USER='rep',
    MASTER_PASSWORD=' Rep123.com',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='master-log.000005',
    MASTER_LOG_POS=154;
mysql> start slave;
mysql> show slave status\G;

db03的操作 (重新启动mha之前一定要删除这个目录下的文件 不然下次转移报错)

[root@db03 ~]# rm -f  /etc/mha_master/app1/*

检查

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

重新启动

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &