MySQL高可用部署-MHA

2022-10-27 14:47:13 浏览数 (2)

MHA简介

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。

MHA 在监控到 master 节点故障时,会提升其中拥有最新数据的 slave 节点成为新的master 节点。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA组成

MHA由两种角色组成:MHA Manager(管理节点)和 MHA Node(数据节点)

  • MHA Manager:可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上
  • MHA node:运行在每台MySQL服务器上

MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。

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

MHA Manager包含以下工具:

  • MHA Master节点:

名称

解释

masterha_check_ssh

检查MHA的SSH配置

masterha_check_repl

检查MySQL主从复制状况

masterga_manager

启动MHA程序

masterha_check_status

检测MHA运行状态

masterha_master_monitor

检测master节点是否可用

masterha_master_swith

故障转移(手动或自动)

masterha_conf_host

添加或删除节点

masterha_stop

关闭MHA服务

  • MHA Node节点

column1

column2

save_binary_logs

保存和复制master的二进制日志

apply_diff_relay_logs

识别差异的中继日志事件并将其差异的事件应用于其他的slave

purge_relay_logs

清除中继日志(不会阻塞SQL线程)

部署mysql主从复制

MHA至少一主两从,否则MHA无法启动

环境如下:

系统

角色

IP

主机名

CentOS7

master

192.168.1.177

mysql-master

CentOS7

slave_01

192.168.1.178

mysql-slave-01

CentOS7

slave_02

192.168.1.179

mysql-slave-02

配置所有节点的hosts文件

代码语言:javascript复制
192.168.1.177	mysql-master
192.168.1.178	mysql-slave-01
192.168.1.179	mysql-slave-02

配置所有节点免密登录

代码语言:javascript复制
ssh-keygen -t rsa
ssh-copy IP

在每个节点上安装perl模块

代码语言:javascript复制
yum install epel-release
yum install perl cpan perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

部署mysql一主多从架构

具体的操作步骤,可以看上一篇文章--MySQL5.7基于GTID的主从配置

部署MHA

下载MHA Manager和MHA Node

https://github.com/yoshinorim/mha4mysql-manager/releases https://github.com/yoshinorim/mha4mysql-node/releases

部署MHA Manager

MHA Manager可以单独部署在一台机器上,也可以部署在其他slave服务器上,要尽量避免安装在master上。

代码语言:javascript复制
yum install epel-release
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager rrdtool perl-rrdtool rrdtool-devel perl-Params-Validate

rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

部署MHA Node

MHA Node需要安装在每一个mysql节点上,而且没有node的话manager也安装不上

代码语言:javascript复制
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

在主库上创建mha用户并授权

代码语言:javascript复制
mysql> grant all on *.* to 'mhaadmin'@'192.168.1.%' identified by '123456';
mysql> grant replication slave on *.* to 'repl'@'192.168.1.%' identified by '123456';

设置所有从库

从库的只读选项不能写在配置文件中,只能在mysql命令行中设置

代码语言:javascript复制
mysql> set global read_only=1

创建MHA配置文件目录和日志目录

代码语言:javascript复制
mkdir -p /etc/mha
mkdir -p /var/log/mha

修改MHA配置文件

配置文件中,不能有空格,需要把注释删掉。

代码语言:javascript复制
vim /etc/mha/mha.cnf

[server default]
manager_log=/var/log/mha/manager.log  
remote_workdir=/apps/data/mysql/		# 设置远端mysql在发生切换时binlog的保存位置 
manager_workdir=/apps/data/mysql/		# MHA工作目录
master_binlog_dir=/apps/data/mysql/		# binlog路径全局配置,如果有节点不一样的话可以单独写在主机标签中
user=mhaadmin					# MHA管理用户,上面创建的mha用户
password=123456					# 管理用户密码
ping_interval=2					# 每2秒检查一次主库状态
repl_user=repl					# 主从复制的用户
repl_password=123456				# 主从复制的密码 
ssh_user=root					# MHA 会使用scp传输日志,所以节点之间做好密钥登录
ssh_port=22                             

[server1]					# 主机标签,数字大小会影响优先级
hostname=192.168.1.103
port=3306
#master_binlog_dir=/data/mysql/binlog		# 单独定义了一个binlog路径
candidate_master=1
 
[server2]
candidate_master=1				# 让该节点成为候选master,即使数据不是最新
#check_repl_delay=0				# 和上面配置配合使用,忽略从库复制延时的问题,否则延迟大于100M的话候选master也不会被选举为master
hostname=192.168.1.104
port=3306
 
[server3]
hostname=192.168.1.108
port=3306
no_master=1					# 不能成为master

#[binlog1]					# 配置一台binlog服务器用来实时备份binlog,防止主库断电导致binlog无法传输,该机器需要有mysql客户端命令
#no_master=1					# 该节点不会被提升为master
#hostname=10.0.0.54
#master_binlog_dir=/data/mysql/binlog

检查MHA配置是否正常

代码语言:javascript复制
masterha_check_ssh --conf=/etc/mha/mha.cnf
masterha_check_repl --conf=/etc/mha/mha.cnf

创建启动MHA启动脚本

代码语言:javascript复制
vim /etc/mha/mha

#!/bin/bash
mha_log='/var/log/mha/mha.log'
mha_cnf='/etc/mha/mha.cnf'

mha_start () {
        mha_processpid=`ps -ef |grep masterha_manager |grep -cv grep`
        if [ ${mha_processpid} -eq 0 ]; then
                nohup masterha_manager --conf=${mha_cnf} > ${mha_log} < /dev/null &
        fi
}

mha_stop () {
        mha_processpid=`ps -ef |grep masterha_manager |grep -cv grep`
        if [ ${mha_processpid} -eq 1 ]; then
                masterha_stop --conf=${mha_cnf} > /dev/null 2>&1
        fi
}

mha_status () {
        mha_processpid=`ps -ef |grep masterha_manager |grep -cv grep`
        if [ ${mha_processpid} -eq 1 ]; then
                echo -e "33[32mMHA is running ! 33[0m"
                masterha_check_status --conf=${mha_cnf}
        else
                echo -e "33[31mMHA has stopped ! 33[0m"
                masterha_check_status --conf=${mha_cnf}
        fi
}

case "$1" in
    start)
    mha_start
    ;;
    stop)
    mha_stop
    ;;
    status)
    mha_status
    ;;
    *)
    echo "USAGE:$0 {start|stop|status}"
esac

启动MHA

代码语言:javascript复制
chmod  x /etc/mha/mha
/etc/mha/mha start
/etc/mha/mha status

测试

  1. 关闭主库
  2. 查看从库状态,是否将主库IP指向到新服务器
  3. 启动原来的主库,把主库IP指向到新服务器

MHA发生切换后,配置文件会被重写,原有的master节点的信息会被删除,所以在恢复了服务后还需要手动在MHA配置文件中增加一台节点

配置Keepalived

keepalived中的2种模式: master->backup:主节点宕机,虚拟IP会自动飘移到从节点,当主节点修复后,keepalived启动后,会把虚拟IP抢占过来,即使设置了非抢占模式(nopreempt),抢占IP的动作也会发生。 backup->backup:主节点宕机,虚拟IP自动漂移到从节点上,当主节点恢复后,并不会抢占虚拟IP,即使是优先级高于从库,也不会发生抢占。

为了减少IP漂移次数,通常是把修复好的主库当做新的备库。

master节点配置

安装配置keepalived
代码语言:javascript复制
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id mysql 			# 两个节点设置一样
}

vrrp_instance VI_1 {
    state BACKUP 			# 两个节点都设置为BACKUP
    interface ens33
    virtual_router_id 58 		# 两个节点设置一样
    priority 100			# 优先级,从设置的要比主小
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1122
    }

    virtual_ipaddress {
        192.168.1.200/24
    }
}

virtual_server 192.168.1.177 3306 { 	# 设置为本机IP
    delay_loop 2
    lb_algo rr
    lb_kind DR
    persistence_timeout 50 
    protocol TCP
    real_server 192.168.1.177 3306 { 
	weight 3
	notify_down /etc/keepalived/chk_mysql.sh
	TCP_CHECK {
	connect_timeout 3
	nb_get_retry 3
	delay_before_retry 3
	}
    }
}
创建检测mysql服务的脚本
代码语言:javascript复制
vim /etc/keepalived/chk_mysql.sh

#!/bin/bash
res = `ps -ef | grep -v grep | grep mysql | wc -l`
if [ $res > 0 ]; then
    exit 0
else
   pkill keepalived
fi
启动服务
代码语言:javascript复制
chmod  x /etc/keepalived/chk_mysql.sh
systemctl start keepalived

ip a			# 查看虚拟IP

slave_01节点配置

安装配置keepalived
代码语言:javascript复制
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id mysql 			# 两个节点设置一样
}

vrrp_instance VI_1 {
    state BACKUP 			# 两个节点都设置为BACKUP
    interface ens33
    virtual_router_id 58 		# 两个节点设置一样
    priority 100			# 优先级,从设置的要比主小
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1122
    }

    virtual_ipaddress {
        192.168.1.200/24
    }
}

virtual_server 192.168.1.178 3306 { 	# 设置为本机IP
    delay_loop 2
    lb_algo rr
    lb_kind DR
    persistence_timeout 50 
    protocol TCP
    real_server 192.168.1.178 3306 { 
	weight 3
	notify_down /etc/keepalived/chk_mysql.sh
	TCP_CHECK {
	connect_timeout 3
	nb_get_retry 3
	delay_before_retry 3
	}
    }
}
创建检测mysql服务的脚本
代码语言:javascript复制
vim /etc/keepalived/chk_mysql.sh

#!/bin/bash
res = `ps -ef | grep -v grep | grep mysql | wc -l`
if [ $res > 0 ]; then
    exit 0
else
   pkill keepalived
fi
启动服务
代码语言:javascript复制
chmod  x /etc/keepalived/chk_mysql.sh
systemctl start keepalived

ip a 				# 查看虚拟IP

0 人点赞