MySQL高可用生成业务需求
在企业实际生产场景中,一主多从的MYSQL数据库架构是最常用的DB架构方案,该架构方案部署简单,维护方便,并且通过配置简单的代理或者通过程序的方式就可以实现应用服务队主从库的读写分离,且多个从库还可以通过LVS或者Haproxy等代理实现多个从库的负载均衡,分担读的压力,同时排除单点问题
但是MYSQL数据库架构中,我们不难发现,虽然从库是多个,但是主库仅有一个,也就是说主库一旦宕机,所以写的业务都会终止,而从库宕机1个就没什么影响,那么如何解决这个主库单点的问题呢,其实最简单的方案就是做好监控,然后主库单机后,有管理人为手工选择最快的从库改为主,然后让其它从库和新的主同步,这个方案是简单易行的,但是需要人工处理,对有些高要求场合高度不够,那样就需要下面说的MySQL+Heartbeat+DRBD架构方案
MySQL+Heartbeat+DRBD架构方案说明:
正常情况下:
1、heartbeat通过串口线或者以太网网线直链网卡对对端的服务做监控检查,并负责执行drbd,mysql,vip等资源的自动切换
2、MYSQL_S作为MYSQL_M的高可用热备,正常情况下MYSQL_M提供一个分区sdb1给MYSQL使用。
3、物理磁盘做RAID10或者RAID0,根据性能和冗余需求来选择
4、服务器之间,服务器和交换机直接都是千兆网卡做bongding
5、应用服务(包括但不限于web)通过VIP访问MYSQL从库,通过不同的VIP访问负载均衡的从库池。
故障情况下:
1、MYSQL_S的heartbeat通过串口线或者以太网网线对MYSQL_M做健康检查,发现MYSQL_M挂掉后,自动在MYSQL_S上启动DRBD/MYSQL等服务及负载VIP的动态切换,确保主库业务被正常接管,自动通过对外提供服务
2、MYSQL_M上的MYSQL在/dev/sdb1分区中,故障后在MYSQL_S上同时实现高可用切换
3、故障后MYSQL客户端,从库等。通过VIP和MYSQL_S的MYSQL 服务相连,MYSQL对外正常提供服务
4、当MYSQL_M故障修复后,可以设置自动把自己原来的业务,从MYSQL_S中取回来,但是一般不建议这样做。如果两台服务器之前存在性能的差异,最好也是人工进行切换
2、MYSQL高可以生产需求描述
本案例假设有3台MYSQL服务器,他们的IP分别是
MYSQL_M 10.0.0.3
MYSQL_S 10.0.0.4
MYSQL_C 10.0.0.5
MYSQL_M的MYSQL目录为/data,前端提供的访问VIP是10.0.0.103
配置目标:一段主MYSQL服务器MYSQL_M宕机,该服务器上的MYSQL和虚拟IP会自动切换当热备服务器MYSQL_S上继续提供服务,从而达到MYSQL高可用宕机后无业务影响的目的
这里会有一个特别的问题,就是以前的多个从库如何能和新的主库同步,经过实践,通过DRBD的方式同步的MYSQL数据库,以及做从库MYSQL时使用和主库VIP为同步VIP,当主MYSQL宕机后,VIP漂移到热备主MYSQL,默认情况在60秒内,从库就可以连接到新的VIP,从而自动和新的主库同步,这里需要强调的下,通过MYSQL同步做双主的方式,是难以做到主库单机从库和新的主库自动同步的。这也是这个架构的难点。
提示:本文讲解的MYSQL数据库服务主备高可用模式,对于MYSQL数据库服务高可用,也可以是主主的双向高可用模式。
3、系统环境
##MYSQL_M #主库,主服务器
eth0:10.0.0.3 #管理IP,用于LAN内数据转发
eth1:172.16.1.3 #MYSQL服务器间心跳连接(直链)
VIP:10.0.0.103 #用于提供对外MYSQL存储系统服务VIP
##MYSQL_S #主库的备用服务器
eth0:10.0.0.4
eth1:172.16.1.4
##MYSQL_C #mysql从库
eth0:10.0.0.5
同时在MYSQL_M需要添加一个1G的磁盘,MYSQL_S需要添加一个1.5G的磁盘。测试用
4、部署前准备
#要配置主机名和hosts文件.
主机名称要以uname -n为准
[root@MYSQL_S ~]# uname -n
MYSQL_S
[root@MYSQL_S ~]# uname -m
x86_64
[root@MYSQL_S ~]#
================================
MYSQL_M
cp /etc/hosts /etc/hosts.bak
cp /etc/sysconfig/network /etc/sysconfig/network.bak
sed -i '$a 10.0.0.3 MYSQL_M' /etc/hosts
sed -i '$a 10.0.0.4 MYSQL_S' /etc/hosts
sed -i '/HOSTNAME=/d' /etc/sysconfig/network
sed -i '/$/aHOSTNAME=MYSQL_M' /etc/sysconfig/network
===============================
MYSQL_S
sed -i '$a 10.0.0.3 MYSQL_M' /etc/hosts
sed -i '$a 10.0.0.4 MYSQL_S' /etc/hosts
sed -i '/HOSTNAME=/d' /etc/sysconfig/network
sed -i '/$/aHOSTNAME=MYSQL_S' /etc/sysconfig/network
############################start测试:
[root@MYSQL_S ~]# ping MYSQL_M
PING MYSQL_M (10.0.0.3) 56(84) bytes of data.
64 bytes from MYSQL_M (10.0.0.3): icmp_seq=1 ttl=64 time=0.347 ms
64 bytes from MYSQL_M (10.0.0.3): icmp_seq=2 ttl=64 time=0.297 ms
^C
--- MYSQL_M ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1424ms
rtt min/avg/max/mdev = 0.297/0.322/0.347/0.025 ms
[root@MYSQL_S ~]# ping MYSQL_S
PING MYSQL_S (10.0.0.4) 56(84) bytes of data.
64 bytes from MYSQL_S (10.0.0.4): icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from MYSQL_S (10.0.0.4): icmp_seq=2 ttl=64 time=0.043 ms
^C
--- MYSQL_S ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1226ms
rtt min/avg/max/mdev = 0.027/0.035/0.043/0.008 ms
[root@MYSQL_S ~]#
===========================
[root@MYSQL_M ~]# ping MYSQL_S
PING MYSQL_S (10.0.0.4) 56(84) bytes of data.
64 bytes from MYSQL_S (10.0.0.4): icmp_seq=1 ttl=64 time=0.720 ms
64 bytes from MYSQL_S (10.0.0.4): icmp_seq=2 ttl=64 time=0.346 ms
64 bytes from MYSQL_S (10.0.0.4): icmp_seq=3 ttl=64 time=0.329 ms
^C
--- MYSQL_S ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2150ms
rtt min/avg/max/mdev = 0.329/0.465/0.720/0.180 ms
[root@MYSQL_M ~]# ping MYSQL_M
PING MYSQL_M (10.0.0.3) 56(84) bytes of data.
64 bytes from MYSQL_M (10.0.0.3): icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from MYSQL_M (10.0.0.3): icmp_seq=2 ttl=64 time=0.131 ms
^C
--- MYSQL_M ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1388ms
rtt min/avg/max/mdev = 0.022/0.076/0.131/0.055 ms
[root@MYSQL_M ~]#
###########################end