mysql学习笔记五 —— MHA

时间:2023-03-08 23:41:35
mysql学习笔记五 —— MHA

MySQL_MHA

ABB(主从复制)-->MHA(实现mysql高可用、读写分离、脚本控制vip飘逸)-->haproxy(对slave集群实现分发,负载均衡)-->keepalive(预防一台haproxy单点故障,对两台及以上的haproxy实现高可用)

一、MHA
MySQL high available mysql高可用
ABB 适用于0~30台服务器

条件:最少3台,即最少为ABB架构

MHA是由一名日本人用Perl语言开发出来的
组成:manager节点 、node节点
工作过程: MHA manager节点定时(按照一定的时间间隔)去检测复制集群中的每一个mha node(ABB),
发现Adown,选出数据跟老A最接近的一台B来作为新A。去到老A,拷贝binlog到新A当中并应用binlog(保证新A与老A数据的一致性),
然后将剩余的slave重新change master to,将slave的主切换为新A。

设置注意:
复制集群中的每个节点都有可能成为A,都得开启binlog
ssh秘钥认证,因为当Adown后,mha要拷贝binglog到所有的节点上,而且所有的节点都有可能成为A,故每个节点都要彼此秘钥认证。
failover:Adown,选出新A,并且尽可能保证数据一致,设置salve重新执行新A

缺点:
保证数据一致性并不总是可行的。硬件raid卡、磁盘损坏,还是会有数据丢失的情况!5.5版本支持半同步,可以提高数据的一致性。
事物提交成功的前提是master已经将binlog交给了复制进群中的一个slave。

实验:
ip规划
mha_manager  19.240    x86_64系统(要求必须是64位操作系统)
master         19.241
slave1     19.242
slave2       19.243

1、ssh秘钥认证
每台机器上都生成root用户的秘钥 ssh-keygen 一路回车
再将公钥彼此共享(互相推送):
#!/bin/bash
for i in 0 1 2 3
do
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.19.24$i
done

将该脚本推送到每台机器上:
[root@MHA_240 opt]# for i in 1 2 3; do scp ssh.sh 192.168.19.24$i:/opt/ ;done

2、ABB 一主多从架构(初始化数据库)
安装软件包:mysql-server mysql perl-* //每台机器上都要安装mysql数据库和perl语言

初始化数据库(每台机器)否则实验可能不成功

编辑配置文件:

241:(master)
server_id=1
log_bin=binlog
log_bin_index=binlog.index

242:(slave1)
server_id=2
log_bin=binlog
log_bin_index=binlog.index

243:(slave2)
server_id=3
log_bin=binlog
log_bin_index=binlog.index

说明:必须都开启binlog日志,复制组中的每一台机器都有可能成为master
server_id 选择新A的依据,越小越优先

241 创建用户并看一下master的状态

mysql> grant replication slave on *.* to 'sky'@'%' identified by '123'; //复制专用用户

mysql> grant all on *.* to 'root'@'%' identified by '123'; //给mha_manager用,因为其在failover时需要登陆上来,并且拷贝binlog到所有的slave上去。

mysql> show master status\G
*************************** 1. row ***************************
File: binlog.000003 //主要看它,直到当前master的binlog
Position: 4
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

242 配置slave
stop slave 
mysql> change master to master_host='192.168.19.241', master_port=3306, master_user='sky', master_password='123', master_log_file='binlog.000003', master_log_pos=4;
Query OK, 0 rows affected (0.01 sec)

mysql>start slave ;
Query OK, 0 rows affected (0.01 sec)

243 配置slave(同上)
stop slave
mysql> change master to master_host='192.168.19.241', master_port=3306, master_user='sky', master_password='123', master_log_file='binlog.000003', master_log_pos=4;
Query OK, 0 rows affected (0.01 sec)

mysql>start slave;
Query OK, 0 rows affected (0.01 sec)

至此ABB搭建完成,建议测试一下看一看能不能同步

mysql学习笔记五 —— MHA

部署mha_manager和mha_node
mha_manager:
cd /usr/src/mha_soft
[root@MHA_240 mha_soft]# rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm      //安装mha_node节点包
[root@MHA_240 mha_soft]# cd dependent/        //安装mha依赖包(可网上下载)

mysql学习笔记五 —— MHA

[root@MHA_240 dependent]# yum install -y localinstall ./*  //安装该目录下所有包
[root@MHA_240 mha_soft]# rpm -ivh mha4mysql-manager-0.55-0.el6.noarch.rpm  //安装mha-manager包

将node包推给复制集群中的所有节点:
[root@MHA_240 mha_soft]# for i in 1 2 3 ;do scp mha4mysql-node-0.54-0.el6.noarch.rpm 192.168.19.24$i:/usr/src ;done

mha_node: 安装node
[root@MHA_240 mha_soft]# rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm

mha_manager: (MHA上)
拷贝相关文件
[root@MHA_240 mha]# cp -pr /usr/src/mha_soft/mha/ /etc/       //mha的配置文件和启动文件

mysql学习笔记五 —— MHA

编辑配置文件:/etc/mha/mha.conf(MHA上)

[server default]
#mysql admin account and password user=root
password= #mha workdir and worklog manager_workdir=/etc/mha
manager_log=/etc/mha/manager.log #mysql A/B account and pw repl_user=sky
repl_password= #check_mha_node time
ping_interval= #ssh account
ssh_user=root [server1]
hostname=192.168.19.241
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master= [server2]
hostname=192.168.19.242
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master= [server3]
hostname=192.168.19.243
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master=

测试ssh互信:
[root@MHA_240 mha]# masterha_check_ssh --conf=/etc/mha/mha.cnf

测试replication复制用户:
[root@MHA_240 mha]# masterha_check_repl --conf=/etc/mha/mha.cnf

开启mha:
开启的方式存放在/etc/mha/mha_start文件中
[root@MHA_240 mha]# nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log </dev/null 2>&1 &

4、failover(故障转移)测试
把Adown掉,看有没有选举出一个新A,并且有没有将slave重新指向新A

二、将老A重新以slave身份加入到复制组
2.1 查看manager日志
cat /etc/mha/manager.log | grep "CHANGE MASTET TO"
Thu Aug 17 15:49:15 2017 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.19.242', MASTER_PORT=3306, MASTER_LOG_FILE='binlog.000003', MASTER_LOG_POS=106, MASTER_USER='sky', MASTER_PASSWORD='xxx';
该日志部分,记录了从老A服务宕掉那一刻binlog文件是哪个以及binlog的位置。可以将该语句修改密码后直接在老A中执行,意思是从binlog.000003中的位置106开始复制到当前master数据库最新的数据

2.2 开启slave
start slave

注意:mha_manager每执行一次failover后,该进程自动退出。如果还想测试failover需要重新开启---开启前要将下面两个文件删掉:
[root@MHA_240 mha]# cd /etc/mha/
[root@MHA_240 mha]# rm -fr mha.failover.complete saved_master_binlog_from_192.168.19.241_3306_20170817154913.binlog

三、master故障后,VIP的漂移
页面-->(HTTP POST)web服务器-->PHP 解析你的请求,并执行相应的脚本将客户端post的数据写入到指定库指定表中-->MySQL
指定一个VIP master

思路一:用 keepalived实现vip漂移

答:不能,当集群中的master宕掉之后,不能确定哪一台被选为新的master,keepalived是通过配置文件中指定的ip漂移,所以不能。

思路二:脚本
判断谁是master,你是master 我把VIP绑定给你
判断你有VIP,但你不是master,去掉你的VIP

测试master发生切换后,VIP自动绑定到新master上,并去掉老master上的VIP,脚本如下:

#!/bin/bash
VIP=192.168.19.250
NETMASK=255.255.255.0
MUSER=root    ##上面定义的给mha拉取binlog到slave的用户
MPW=
MYSQL_IP="192.168.19.241 192.168.19.242 192.168.19.243" ##mha_manager检测ip
NIC=eth0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~main program~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#check_master_mysql
check_master() {
for IP in $MYSQL_IP
do
if ssh $IP "lsof -i :3306" &>/dev/null;then
ssh $IP "mysql -uroot -p123 -e 'show slave status \G'|grep -w 'Slave_IO_Running'" &>/dev/null
if [ $? -eq ];then
MY_master=$IP
echo "$MY_master"
fi
fi
done
}
#check_master
#echo $MY_master
#set_VIP() {
#ssh $MY_master "ip add show eth0"|grep inet|grep "$VIP"
# if [ $? -ne ];then
# ifconfig $NIC: $VIP netmask $NETMASK up
# fi
#}
check_master_alive() {
for IP in $MYSQL_ip
do
if ssh $IP "ip add show eth0"|grep inet|grep "$VIP" &>/dev/null;then
ssh $IP "lsof -i:3306" &>/dev/null
if [ $? -ne ];then
ssh $IP "ifconfig $NIC:250 down "
fi
fi
done
} VIP () {
for IP in $MYSQL_IP
do
ssh $IP "ip add show eth0"|grep inet|grep "$VIP" &>/dev/null
if [ $? -eq ] && [ $MY_master != "$IP" ];then
ssh $IP "ifconfig $NIC:250 down"
elif [ $? -eq ] && [ $MY_master == "$IP" ];then
ssh $IP "ifconfig $NIC:250 $VIP netmask $NETMASK up"
fi
done
} while true
do
check_master
check_master_alive
VIP
sleep
done

四、haproxy部署slave的负载均衡
lvs nginx haproxy

ip 规划:
mha_manager(monitor): 240
master 242
slave_1 241
slave_2 243
VIP 244 //绑定到master,针对写操作
haproxy 245 //搭建slave集群

4.1 部署
# tar xf haproxy-1.5.3.tar

# cd haproxy-1.5.3

# make TARGET=linux26 PREFIX=/usr/local/haproxy //TARGET指定内核版本 PREFIX指定安装路径
# make install PREFIX=/usr/local/haproxy

# cp /usr/src/haproxy/haproxy-1.5.3/examples/haproxy.cfg /usr/local/haproxy/ //拷贝配置文件到安装路径下
# cp /usr/src/haproxy/haproxy-1.5.3/examples/init.haproxy /etc/init.d/haproxy //启动管理脚本
# ll /etc/init.d/haproxy //查看有没有执行权限
# cp /usr/local/haproxy/sbin/haproxy /usr/sbin/ //拷贝执行程序
# mkdir /etc/haproxy //创建目录用于存放配置文件
# ln -s /usr/local/haproxy/haproxy.cfg /etc/haproxy/ //配置文件链接
# mkdir /usr/share/haproxy //主程序运行时的根目录,必须是空目录

五、读写分离过程示例

客户端-->web-->静态页面 web
>php -->解析 读 链接haproxy-->slave 1 slave2
>php -->解析 写 链接masterVIP -->master --->slave 过来同步