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 statusG
*************************** 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
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依赖包(可网上下载)
[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的漂移
页面-->(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=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的负载均衡
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 过来同步