mysql学习笔记五 —— MHA
MySQL_MHA
ABB(主从复制)-->MHA(实现mysql高可用、读写分离、脚本控制vip飘逸)-->haproxy(对slave集群实现分发,负载均衡)-->keepalive(预防一台haproxy单点故障,对两台及以上的haproxy实现高可用)
一、MHA
MySQL high available mysql高可用
ABB 适用于0~30台服务器
条件:最少3台,即最少为ABB架构
组成: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搭建完成,建议测试一下看一看能不能同步
部署mha_manager和mha_node
安装包下载地址:(外网)
https://code.google.com/archive/p/mysql-master-ha/downloads
生产快速部署实例:
#线上环境: centos7.9 #mha版本 mha4mysql-node-0.56-0.el6.noarch.rpm mha4mysql-manager-0.56-0.el6.noarch.rpm #安装依赖 yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Config-IniFiles perl-Time-HiRes #安装node yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm #安装manager yum install -y mha4mysql-manager-0.56-0.el6.noarch.rpm #配置文件如后面实验
实验开始:
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依赖包(可网上下载)
或者直接使用yum安装
yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-ParallelForkManager \
perl-Config-IniFiles ncftp perl-Params-Validate perl-CPAN perl-TestMock-LWP.noarch \
perl-LWP-Authen-Negotiate.noarch perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
[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的配置文件和启动文件
编辑配置文件:/etc/mha/mha.conf(MHA上)
[server default] #mysql admin account and password user=root password=123 #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=123 #check_mha_node time ping_interval=1 #ssh account ssh_user=root [server1] hostname=192.168.19.241 ssh_port=22 master_binlog_dir=/var/lib/mysql candidate_master=1 [server2] hostname=192.168.19.242 ssh_port=22 master_binlog_dir=/var/lib/mysql candidate_master=1 [server3] hostname=192.168.19.243 ssh_port=22 master_binlog_dir=/var/lib/mysql candidate_master=1
测试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的漂移
思路一:用 keepalived实现vip漂移
答:不能,当集群中的master宕掉之后,不能确定哪一台被选为新的master,keepalived是通过配置文件中指定的ip漂移,所以不能。
当然,如果只有两台数据库一主一备的情况下,可以使用keepalived,因为已经能确定ip会漂移到哪台服务器了。
思路二:脚本
注:VIP也可考虑如:云服务器高可用虚拟IP(VIP),该方案甚至可以不用下面脚本控制VIP漂移,客户端发出写请求VIP,
如果master机故障,该VIP会将请求转发给备机,达到高可用目的。
脚本原理:
判断谁是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=123 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 1 ];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 0 ];then # ifconfig $NIC:200 $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 0 ];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 0 ] && [ $MY_master != "$IP" ];then ssh $IP "ifconfig $NIC:250 down" elif [ $? -eq 1 ] && [ $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 1 done
四、haproxy部署slave的负载均衡(slave集群)
可使用: lvs nginx haproxy等
ip 规划:
mha_manager(monitor): 240
master 242
slave_1 241
slave_2 243
VIP 244 //绑定到master,针对写操作
haproxy 245 //搭建slave集群
具体操作见下一篇:
mysql高可用架构之MHA,haproxy实现读写分离详解
五、读写分离过程示例
客户端-->web-->静态页面 web-->php -->解析 读 链接haproxy-->slave 1 slave2
客户端-->web-->php -->解析 写 链接masterVIP -->master<--slave 过来同步
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步