MySQL高可用架构之MHA

一、运维人员需要掌握的MySQL技术:

1、基本SQL语句

2、基本的管理【库表数据的管理    权限的管理】

3、容灾       保证数据不丢失。

二、工作中MySQL的问题:

AB不同步怎么办?

1)如果当天及时发现的:先基于当前同步,再做差异还原

2)好几天才发现:重做B

三、数据完整性如何实现?

1)AB同步 

AB互为主备+keepalived

php连接VIP,如果master宕机,slave承担访问流量;但如果master回来了,来承当访问流量并且造成数据不一致的情况(MHA解决这种问题,当A回来了进行差异还原使数据一致)。

  2)MySQL注入

MySQL注入:登上你MySQL,删掉数据(在数据库层),然后所有的服务器就没数据了

备份策略:每周全备一次,每天增量备份

  3)数据量的增长

IO成为瓶颈—分析业务(1、读多写少;2、读多写多;3、读少写多)

以读多写少的情况为例:

读写分离     A负责写             B负责读

因为读的要求较多,一台B效率低,所以架构演变成ABBB(一主多从),并把B做成集群,以提高读效率。

那么,当A宕机了,由哪个B来负责写入呢?

通过选举机制,从B中选出一个来当A,然后所有的B给新A做备份,并保证数据的完整性!******

四、MHA实现机制:

监控AB的状态

完整的选举机制(看谁的数据跟master最接近)

让一个B切换到新A

保证数据的完整性(通过差异还原)

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

   该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

  在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

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

假如MySQL MHA架构运行正常,突然在上午10:00一个复制组中的A的MySQL服务 down了!

因为AB复制是异步复制,所以可能有一些数据尚没有被B拉到其relay_log中,即AB数据不一致,MHA是怎样解决这种情况的呢?

1、mha_manager 使用scp命令将A当前binlog拷贝到mha_manager

2、待新A(选举:依据谁的relay_log新)产生后,mha_manager再拿着旧A的binlog和新的relay_log做比对,并进行差异还原以保证新A和旧A数据的一致性

3、mha_manager最后拿着老A的binlog去找复制组中其他B 做差异还原,保证数据的一致性

实验步骤:

1)            ssh证书户信任(ssh的密钥验证)

2)            ABB架构()

3)            安装mha_manager  、 mha_node

4)            测试

IP地址规划

Mysql_manager(18.240)—需要是64位的系统

MySQL_A(18.241)

MySQL_B1(18.242)

MySQL_B2(18.243)

1、ssh证书互信脚本---每台机器上都要操作

1.1使用ssh-kegen生成公私钥(每台服务器上)

1.2执行脚本

#!/bin/bash

for i in 0 1 2 3

do

ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.18.24$i

done

2、ABB搭建

2.1测试yum仓库的可用性脚本

#!/bin/bash

for i in 0 1 2 3

do

ssh 192.168.18.24$i     "

if ( yum install telnet-server -y ) > /dev/null 2>&1;then

echo "192.168.18.24$i Yum is TURE"

else

echo "192.168.18.24$i Yum is FALSE "

fi

"

done

2.2安装脚本:

#!/bin/bash

for i in 0 1 2 3

do

ssh 192.168.18.24$i     "

if ( yum install mysql mysql-server perl-* -y ) > /dev/null 2>&1;then

echo "192.168.18.24$i installation finish"

else

echo "192.168.18.24$i installation error "

fi

"

done

2.3所有的机器初始化MySQL,设置ABB架构:

MYSQL_A(241)上的操作:

vim /etc/my.cnf

server_id=1       //设置优先级最高

log_bin=binlog  //开启binlog日志

log_biin=binlog.index

MYSQL_B1、MYSQL_B2上的操作同mysql_a只是注意server_id的不同!

2.4 设置用户

在msyql_a(241)中:因为前面已经开启二进制日志了,所以其他机器也能学到赋权语句!!故,其他机器就不用再赋权了!

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

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

> flush privileges;    //刷新权限

> show master status\G        //看一下binlog日志到第几个文件了

在mysql_b1(242)中:

  • slave stop;
  • change master to master_host=”192.168.18.241”,master_user=”sky”,master_passoword=”123”,master_log_file=”binlog.000001”;
  • slave start;
  • show slave status\G        //查看复制线程状态

在mysql_b2(243)做242上同样的操作!

3、安装配置启动mha_manager、mha_node

3.1安装

manager机器上:

cd /usr/src/mha_soft

[root@localhost mha_soft]# rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm      //安装node

cd dependent

yum -y install localinstall ./*               //装上依赖

cd ..

rpm -ivh mha4mysql-manager-0.55-0.el6.noarch.rpm   //安装manager

mha_manager的配置文件:

[root@localhost mha]# cp -r mha /etc/

mha目录下主要有以下两个文件

mha.cnf   mha_start

[root@localhost mha]# vim /etc/mha/mha.cnf            //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.18.241
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master= [server2]
hostname=192.168.18.242
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master= [server3]
hostname=192.168.18.243
ssh_port=
master_binlog_dir=/var/lib/mysql
candidate_master=

vim /etc/mha/mha_start       //启动脚本

nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log </dev/null >& &

其他节点:

安装mha4mysql-node…rpm包(直接rpm安装即可)

3.2 检测ssh互信有没有问题

[root@localhost src]# masterha_check_ssh --conf=/etc/mha/mha.cnf

Tue Jun 13 02:21:31 2017 - [info] All SSH connection tests passed successfully.

3.3 测AB

[root@localhost src]# masterha_check_repl --conf=/etc/mha/mha.cnf

MySQL Replication Health is OK.

3.4 启动

[root@localhost src]# cat /etc/mha/mha_start    //先看一下启动方式

nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log </dev/null 2>&1 &

运行:

[root@localhost src]# nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log </dev/null 2>&1 &

3.5 测试

现在两个slave的Master_Host同为241,把241干掉后,就会选举新的master了!

先在mha_manager上打开日志:

# tailf /etc/mha/manager.log

到241上关闭MySQL服务:

service mysqld stop

查看mha_manager日志输出:

…           //此处省略

----- Failover Report -----

mha: MySQL Master failover 192.168.18.241 to 192.168.18.242 succeeded

Master 192.168.18.241 is down!

Check MHA Manager logs at localhost.localdomain:/etc/mha/manager.log for details.

Started automated(non-interactive) failover.

The latest slave 192.168.18.242(192.168.18.242:3306) has all relay logs for recovery.

Selected 192.168.18.242 as a new master.

192.168.18.242: OK: Applying all logs succeeded.

192.168.18.243: This host has the latest relay log events.

Generating relay diff files from the latest slave succeeded.

192.168.18.243: OK: Applying all logs succeeded. Slave started, replicating from 192.168.18.242.

192.168.18.242: Resetting slave info succeeded.

Master failover to 192.168.18.242(192.168.18.242:3306) completed successfully.

 

看来242变成了master!~

可以去新主上创建个库或到243上查看一下master.info来验证!!

老master恢复后如果想要它再做master,要先将新master的数据同步,之后删除下面两个文件,再重新开启MHA功能,令新master宕掉即可(实验可行,实际操作不推荐)如下:

注意:mha_manager每执行一次failover后,该进程自动退出。如果还想测试failover需要重新开启---开启前要将下面两个文件删掉:

[root@MHA_243 mha]# cd /etc/mha/

[root@MHA_243 mha]# rm -fr mha.failover.complete saved_master_binlog_from_192.168.19.241_3306_20170817154913.binlog

下面演示old_master回来,如何保证old_master同步new_master的新产生的数据:

当old_master服务宕掉后,去mha_monitor上执行:

[root@mha_master mha]# grep -i change /etc/mha/manager.log (-i 是不区分大小写)

Tue Jun 13 02:30:23 2017 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.18.242', MASTER_PORT=3306, MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=106, MASTER_USER='sky', MASTER_PASSWORD='xxx';

然后在old_master上执行:

mysql> slave stop;

mysql> change master to  master_host='192.168.18.242', master_port=3306, master_log_file='binlog.000001', master_log_pos=106, master_user='sky', master_password='123';(只需要修改密码即可)

mysql> slave start;

4、MHA failover(master故障)后VIP漂移

MHA架构中,master来承担写请求,但是如果发生了failover,那么就应该让new_master来承担写请求,有哪些方式可以实现呢?

1、            改变master的IP:在web上修改PHP页面的代码(所有写请求修改成new_master的IP)

2、            使用虚拟IP(VIP),将VIP漂移给new_master

显然,第二种方案要更加容易实现、高效。

实现起来,大家可能会首当其冲的想到keepalived,但是在这里不适用,因为我们不好判断哪一个salve会在failover后变成master(在keepalived中,VIP根据物理路由器的优先级来确定,万一漂到一台slave上那可如何是好!)。不过我们可以通过脚本的方式来实现将VIP绑定到new_master上。

脚本思路如下:

脚本(/etc/mha/check_mysql)运行在manager上,它来管理VIP

判断谁是主,确保它有VIP,并继续判断,如果slave有VIP,则收回。

脚本名称:master_vip_drift.sh

脚本需要根据前面设置的数据库密码对应修改,此处设置的为用户root,密码123

#!/bin/bash
VIP=192.168.18.245
NETMASK=255.255.255.0
MUSER=root
MPW=
MYSQL_IP="192.168.18.241 192.168.18.242 192.168.18.243"
NIC=eth0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~main program~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#check_master_mysql
check_master() {     #检测谁是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_alive() {  #检测master的存活状态
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:245 down "
fi
fi
done
} VIP () {    #给master赋予VIP,不是master收回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 #如果有VIP但是不是master,收回VIP
ssh $IP "ifconfig $NIC:245 down"
elif [ $? -eq ] && [ $MY_master == "$IP" ];then   #如果没有VIP却是master,赋予其VIP
ssh $IP "ifconfig $NIC:245 $VIP netmask $NETMASK up"
fi
done
} while true
do
check_master
check_master_alive
VIP
sleep
done

当前实验环境:

241              mysql_a

243              mysql_b2

242              mysql_b1           新 master

245              VIP

240              mha_monitor

1. 重新运行masterha_manager:

[root@mha_master mha]# nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log </dev/null 2>&1 &

2. 重新运行脚本master_vip_drift.sh

[root@mha_master mha]# ./master_vip_drift.sh  &

3. 去242上检查VIP有没有绑定上

4. 模拟242的MySQL服务宕掉

5. 看看monitor上的日志,找出谁是新master

6、验证241上有没有VIP,242上的VIP有没有被收回

***monitor进行一次failover后自动关闭,还需手动运行

***需手动删除/etc/mha/下的失败切换文件failover file和binlog,否则failover不成功!

5、分析failover日志—了解MHA工作流程

5.1 tailf /etc/mha/manager.log

5.2 到master上关闭MySQL服务

5.3 查看日志并从头往下捋一遍

6、MySQL MHA读写分离后将slave做成集群

用的是HAProxy这款支持七层和四层分发的将slave做成集群,来承担读请求

实现读写分离:

通过修改PHP页面中绑定的IP地址,master承担请求用VIP,slave集群承担请求用haproxyIP

实验环境:

241              mysql_a              //master

242              mysql_b1

243              mysql_b2

245              VIP(master)

246              mha_monitor

247              HAProxy

248              client/httpd(lamp)

大致结构图如下:

结构图说明:

a.MHA对abb架构实行监控,发现a宕之后选出新a(实现VIP漂移,仅a有VIP)

b.haproxy对slave集群实现负载均衡,承担读请求

c.web集群请求后台数据,写请求传给a(VIP),读请求传给haproxy,haproxy再对读请求实现分发达到负载均衡

6.1  安装HAProxy

yum install gcc -y

tar xf haproxy-1.5.3.tar

make TARGET=linux26 PREFIX=/usr/local/haproxy

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/haproxy.init /etc/init.d/haproxy

chmod 755 /etc/init.d/haproxy

ln -s /usr/local/haproxy/sbin/* /usr/sbin/

mkdir /etc/haproxy

mkdir /usr/share/haproxy

ln -s /usr/local/haproxy/haproxy.cfg /etc/haproxy/

cd ..

6.2  设置配置文件

6.2.1 拷贝配置文件

[root@HAProxy_247 haproxy]# cp haproxy.cfg  /usr/local/haproxy/

cp: overwrite `/usr/local/haproxy/haproxy.cfg'? y

6.2.2      编辑配置文件

[root@HAProxy_247 haproxy]# vim /usr/local/haproxy/haproxy.cfg

注意修改RS的IP:

# this config needs haproxy-1.1. or haproxy-1.2.

global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn
chroot /usr/share/haproxy
uid
gid
daemon
#debug
#quiet defaults
log global
mode http
#option httplog
option dontlognull
retries
option redispatch
maxconn
contimeout
clitimeout
srvtimeout listen MySQL 0.0.0.0:
mode tcp
maxconn
balance roundrobin
option mysql-check user root
server mysql_1 192.168.18.242: inter 1s rise fall
server mysql_2 192.168.18.243: inter 1s rise fall listen admin_status
mode http
bind 0.0.0.0:
option httplog
log global
stats enable
stats refresh 10s
stats hide-version
stats realm Haproxy\ Statistics
stats uri /admin-status
stats auth admin:
stats admin if TRUE

6.3  启动HAProxy服务

[root@HAProxy_247 haproxy]# service haproxy start

6.4  访问HAProxy的网页

http://localhost:8899/admin-status

用户名密码查看配置文件舍子

6.5  客户端测试---密码123

6.6 回到HAProxy管理界面,可以看到那台slave响应的请求

mysql高可用架构之MHA,haproxy实现读写分离详解的更多相关文章

  1. (转)MySQL高可用架构之MHA

    MySQL高可用架构之MHA  原文:http://www.cnblogs.com/gomysql/p/3675429.html 简介: MHA(Master High Availability)目前 ...

  2. MySQL高可用架构之MHA

    简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是 ...

  3. 转一下大师兄的"MySQL高可用架构之MHA"

    简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是 ...

  4. MySQL高可用架构之MHA(转)

    简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是 ...

  5. mysql高可用架构之-MHA学习

    此博文参考  博主:mysql高级DBA yayun  完成 简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司 ...

  6. MySQL 高可用架构 之 MHA (Centos 7.5 MySQL 5.7.18 MHA 0.58)

    目录 简介 环境准备 秘钥互信 安装基础依赖包 安装MHA组件 安装 MHA Node组件 安装 MHA Manager 组件 建立 MySQL 一主三从 初始化 MySQL 启动MySQL 并简单配 ...

  7. MySQL高可用架构之MHA 原理与实践

    MHA简介 关于MHA MHA(Master HA)是一款开源的MySQL的高可用程序,它为MySQL主从复制架构提供了automating master failover 功能.MHA在监控到mas ...

  8. 【MySQL】MySQL高可用架构之MHA

    一.关于MHA MHA(Master HA)是一款开源的MySQL的高可用程序,它为MySQL主从复制架构提供了automating master failover 功能.MHA在监控到master节 ...

  9. MySQL高可用系列之MHA(二)

    一.參数说明 MHA提供了一系列配置參数.深入理解每一个參数的详细含义,对优化配置.合理使用MHA非常重要.非常多高可用性也都是通过合理配置一些參数而实现的. MHA包含例如以下配置參数,分别说明例如 ...

随机推荐

  1. Flask中无法在其他函数中查询Sqlachemy的解决办法

    报错信息部分截取: File "D:\python 3.5\lib\site-packages\flask_sqlalchemy\__init__.py", line 912, i ...

  2. Spring Security(二十八):9.4 Authentication in a Web Application

    Now let’s explore the situation where you are using Spring Security in a web application (without we ...

  3. copyOf数组复制方法的使用(数组扩容练习)

    package com.Summer_0420.cn; import java.util.Arrays; /** * @author Summer * 我们使用数组存储了50名学生的考试信息 , 今天 ...

  4. AI numpy

    nan:not a number inf:infinate arange(start, stop, step):[start, stop),step是步长的数组 sin:正弦函数 cos:余弦函数

  5. IDEA+Maven+Tomcat构建项目流程

    0.准备 本文主要解决在IDEA上开发Maven-webapp项目关联Tomcat的问题. 首先,确保本地计算机下载解压了Tomcat压缩包,以及配置好了Java环境. 1.新建Mavne项目 2.I ...

  6. 《React Native 精解与实战》书籍连载「React Native 中的生命周期」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  7. python四:函数练习--小白博客

    为什么要有函数?函数式编程定义一次,多出调用函数在一定程度上可以理解为变量函数的内存地址加上()就是调用函数本身也可以当做参数去传参 不用函数:组织结构不清晰代码的重复性 def test():#te ...

  8. 各种jar包

    springframework下载地址:http://maven.springframework.org/release/org/springframework/spring/ commons开头的j ...

  9. XT535

    今天金山误删了一个文件,把手机系统整坏了,故刷了个机,刷机教程: http://bbs.dospy.com/thread-15027415-1-623-1.html 中间安装了个驱动精灵,否则手机开启 ...

  10. Vue之子组件

    全局组件 <script src="./static/vue.min.js"></script> // 导入vue <body> <div ...