Mycat - 高可用与负载均衡实现,满满的干货!

前情回顾mysql

Mycat - 实现数据库的读写分离与高可用中咱们实现了mysql的读写分离与高可用,有几个点咱们回顾下nginx

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。算法

一、数据的同步在mysql层面实现的,mycat不负责任何的数据同步,咱们须要配置mysql的主从复制来实现数据的同步;sql

二、数据库的读写分离是mycat最经常使用的场景之一,咱们的应用代码只须要关注业务代码,而不须要处理数据库读写、分片问题,这些都由Mycat实现,简化了开发;数据库

三、读写分离每每伴随着高可用,而Mycat同时支持这二者;后端

那是否是就天衣无缝了呢? 显然还有点小瑕疵,此时咱们的Mycat是单点部署的,若是Mycat服务挂了,那么整个数据库端就挂了,整个应用也就不能正常服务了,那怎么办了? 很明显,咱们须要实现Mycat的高可用,具体实现咱们往下看。centos

keepalived实现Mycat高可用bash

centos7_1 (192.168.1.110)上搭建mycat服务器

上篇博文中,咱们搭建的读写分离各组件关系以下网络

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

此时仍是单节点的mycat,咱们还须要搭建一个mycat,搭建过程能够参考192.168.1.212上mycat的搭建,具体我就不演示了,搭建好以后各组件关系以下

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

昨天咱们测试了master mysql宕机的状况,后续的DML SQL与Select SQL都是走的slave mysql,因此此时mysql的主从复制已经被破环、mycat的writeHost也切换到了192.168.1.211,咱们须要从新配置mysql的主从复制,192.168.1.210还是主,192.168.1.211回退为slave,并将192.168.1.212上mycat的writeHost进行还原(只须要将mycat/conf/dnindex.properties文件删了便可);生产环境不要这么处理,按上篇说的处理。

咱们来看下测试结果

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

能够看到,192.168.1.110上的mycat与192.168.1.212上的mycat具备彻底同样的功能,但此时二者尚未任何联系,彼此也互不影响。咱们能够在应用代码中集成两个mycat,由代码控制mycat的高可用,这种方式可行但不可取,代码应该更多的关注业务层,而不是处理数据库层面的高可用问题。mycat的高可用应该就由更专业的组件来处理。

keepalived实现vip对外提供服务

VIP:192.168.1.200、master:192.168.1.2十二、backup:192.168.1.110

keepalived的搭建过程可参考:主从热备+负载均衡(LVS + keepalived),这里就不作详细的演示了。

192.168.1.212(master)上keepalived.conf

global_defs {
 notification_email {
 997914490@qq.com
 }
 notification_email_from sns-lvs@gmail.com
 #smtp_server smtp.hysec.com
 #smtp_connection_timeout 30
 router_id mycat_master # 设置mycat master的id,在一个网络应该是惟一的
}
vrrp_script chk_mycat_alive {
 script "/usr/local/src/mycat/check_pid.sh" # 返回状态码为0表示正常,检测脚本为true;返回状态码非0表示异常,检测脚本为false
 interval 2 # 检测脚本执行的间隔,单位是秒
 weight 20
}
vrrp_instance VI_1 {
 state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备
 interface eth0 # 当前进行vrrp通信的网络接口卡(当前centos的网卡)
 virtual_router_id 66 # 虚拟路由编号,同集群,主备必须一致
 priority 100 # 优先级,数值越大,获取处理请求的优先级越高
 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
 authentication {
 auth_type PASS
 auth_pass 1111
 }
 track_script {
 chk_mycat_alive # 调用检测脚本
 }
 virtual_ipaddress {
 192.168.1.200 # 定义虚拟ip(VIP),可多设,每行一个
 }
}

 192.168.1.110(backup)上keepalived.conf

global_defs {
 notification_email {
 997914490@qq.com
 }
 notification_email_from sns-lvs@gmail.com
 #smtp_server smtp.hysec.com
 #smtp_connection_timeout 30
 router_id mycat_backup # 设置mycat backup的id,在一个网络应该是惟一的
}
vrrp_script chk_mycat_alive {
 script "/usr/local/src/mycat/check_pid.sh" #mycat检测脚本
 interval 2 #(检测脚本执行的间隔,单位是秒)
 weight 20
}
vrrp_instance VI_1 {
 state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备
 interface enp0s3 # 当前进行vrrp通信的网络接口卡(当前centos的网卡)
 virtual_router_id 66 # 虚拟路由编号,同集群,主备必须一致
 priority 90 # 优先级,数值越大,获取处理请求的优先级越高
 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
 authentication {
 auth_type PASS
 auth_pass 1111
 }
 track_script {
 chk_mycat_alive #(调用检测脚本)
 }
 virtual_ipaddress {
 192.168.1.200 # 定义虚拟ip(VIP),可多设,每行一个
 }
}

mycat存活检测脚本check_pid.sh

#!/bin/bash
count=`/usr/local/mycat/bin/mycat status |grep 'Mycat-server is running' | wc -l`
time=$(date "+%Y-%m-%d %H:%M:%S")
if [ $count = 0 ]; then
 echo "$time : count=$count, mycat is not running..." >> /var/log/keepalived_check.log
 exit 1 # 返回1说明脚本非正常执行,mycat不在运行中
else
 echo "$time : count=$count, mycat is running..." >> /var/log/keepalived_check.log
 exit 0 # 返回0说明脚本正常执行,mycat正在运行中
fi

脚本目录:/usr/local/src/mycat/,给脚本可执行权限:[root@centos7-01 src]# chmod -R 755 mycat/check_pid.sh

各组件关系图以下

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

如上图所示,外部应用向192.168.1.200发送sql请求,keepalived完成VIP到ip的映射,请求会落到具体的某个mycat上,再由mycat转发到具体的mysql上。同一时刻只会有一个keepavlied处理VIP,通常而言是优先级高的keepalived会成为master,负责VIP的映射。各组件配置好以后,咱们来看看测试结果

一、vip的正常绑定与切换

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

一开始212和110都没有启动mycat,优先级分别是100,90,因此vip在212上,212成为master,110成为backup;接着咱们启动了110上的mycat,检测脚本返回0,vrrp_script中script为true,此时110的权重=90+20,大于212的100,110抢占vip成为master,而212则降级成为backup;而后咱们启动了212上的mycat,212的权重=100+20,大于110的110,vip漂浮到212上,212成为master,110成为backup;最后咱们停了212上的mycat,权重=100,vip又漂到了110上。若是咱们接着停了110上的mycat,则vip又会漂到212上。

权重 = priority + weight * script的结果(脚本执行返回0,script则为true,不然script为false),权重大的抢占到vip,成为master;杀掉keepalived进程,vip也会进行正确的转移,具体我就不展现测试结果,你们能够自行去测试。

二、mycat高可用

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

咱们经过vip能够进行正常的sql请求,当212上的mycat停了,vip漂到了110上,经过vip仍然能够进行sql请求,应用端根本感知不到后端vip的漂移、mycat的切换,实现了mycat的高可用。

这种方案已经能够知足大多数的应用场景了,master上的mycat对外服务,backup上的mycat仅做为备用以防master宕机,backup上的mycat基本上不提供服务,就是起到一个以防万一的做用,并发量不高的应用采用此种方案就能够了。若是并发量高了,master上的mycat压力太大,那咱们就须要考虑将backup上的mycat也利用起来了,并作一个负载均衡,减轻master上的mycat压力,并充分利用backup上的mycat,具体实现请往下看。

lvs实现Mycat的负载均衡

Mycat的高可用是实现了,但美中不足的是没有物尽其用,咱们不难发现,Mycat的两个节点其实只有一个对外服务,另外一个彻底备用(以备基本不会发生的宕机),宕机的几率原本就小,备用机基本至关于没用了,那可不能够将备用机利用起来了? 咱们能够将主备Mycat都利用起来,并进行负载均衡,减少主Mycat的压力,若是其中一个节点宕机了,则由另外一个节点彻底接管,继续正常提供服务。

Mycat - 高可用与负载均衡实现,满满的干货!

 

 

组件结构图如上所示,keepalived负责lvs的健康检测与高可用,lvs负责mycat的负载均衡与心跳检测。若是服务器不够,keepalived、lvs和mycat能够部署在一块儿,但不推荐,组件都部署在同一个服务器上,风险太大,分散部署,能够下降风险。keepalived + lvs的具体部署过程可参考主从热备+负载均衡(LVS + keepalived),具体配置文件以下

192.168.1.214(master)上keepalived.conf

global_defs {
 notification_email {
 997914490@qq.com
 }
 notification_email_from sns-lvs@gmail.com
 #smtp_server smtp.hysec.com
 #smtp_connection_timeout 30
 router_id lvs_master # 设置lvs master的id,在一个网络应该是惟一的
}
vrrp_instance VI_1 {
 state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备
 interface eth0 # 当前进行vrrp通信的网络接口卡(当前centos的网卡)
 virtual_router_id 66 # 虚拟路由编号,主从要一致
 priority 100 # 优先级,数值越大,获取处理请求的优先级越高
 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
 authentication {
 auth_type PASS
 auth_pass 1111
 }
 virtual_ipaddress {
 192.168.1.200 # 定义虚拟ip(VIP),可多设,每行一个
 }
}
virtual_server 192.168.1.200 8066 { #设置虚拟服务器,须要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
 delay_loop 6 #设置运行状况检查时间,单位是秒
 lb_algo rr #设置负载调度算法,这里设置为rr,即轮询算法
 lb_kind DR #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
 nat_mask 255.255.255.0
 persistence_timeout 0 #会话保持时间,单位是秒;同一IP x秒内的请求都发到同个real server
 protocol TCP #指定转发协议类型,有TCP和UDP两种
 
 real_server 192.168.1.212 8066 { #配置服务节点1,须要指定real server的真实IP地址和端口,IP与端口之间用空格隔开
 weight 3 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小能够为不一样性能的服务器
 TCP_CHECK { #realserver的状态检测设置部分
 connect_timeout 10 #表示10秒无响应超时
 nb_get_retry 3 #表示重试次数
 delay_before_retry 3 #表示重试间隔
 }
 }
 real_server 192.168.1.110 8066 {
 weight 3
 TCP_CHECK {
 connect_timeout 10
 nb_get_retry 3
 delay_before_retry 3
 }
 }
}

192.168.1.213(backup)上keepalived.conf

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。

global_defs {
 notification_email {
 997914490@qq.com
 }
 notification_email_from sns-lvs@gmail.com
 #smtp_server smtp.hysec.com
 #smtp_connection_timeout 30
 router_id lvs_backup # 设置lvs backup的id,在一个网络应该是惟一的
}
vrrp_instance VI_1 {
 state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备
 interface eth0 # 当前进行vrrp通信的网络接口卡(当前centos的网卡)
 virtual_router_id 66 # 虚拟路由编号,主从要一致
 priority 100 # 优先级,数值越大,获取处理请求的优先级越高
 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
 authentication {
 auth_type PASS
 auth_pass 1111
 }
 virtual_ipaddress {
 192.168.1.200 # 定义虚拟ip(VIP),可多设,每行一个
 }
}
virtual_server 192.168.1.200 8066 { #设置虚拟服务器,须要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
 delay_loop 6 #设置运行状况检查时间,单位是秒
 lb_algo rr #设置负载调度算法,这里设置为rr,即轮询算法
 lb_kind DR #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
 nat_mask 255.255.255.0
 persistence_timeout 0 #会话保持时间,单位是秒;同一IP x秒内的请求都发到同个real server
 protocol TCP #指定转发协议类型,有TCP和UDP两种
 
 real_server 192.168.1.212 8066 { #配置服务节点1,须要指定real server的真实IP地址和端口,IP与端口之间用空格隔开
 weight 3 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小能够为不一样性能的服务器
 TCP_CHECK { #realserver的状态检测设置部分
 connect_timeout 10 #表示10秒无响应超时
 nb_get_retry 3 #表示重试次数
 delay_before_retry 3 #表示重试间隔
 }
 }
 real_server 192.168.1.110 8066 {
 weight 3
 TCP_CHECK {
 connect_timeout 10
 nb_get_retry 3
 delay_before_retry 3
 }
 }
}

 192.168.2十二、192.168.1.110上的realserver.sh内容一致

#!/bin/bash
VIP=192.168.1.200
/etc/rc.d/init.d/functions
 
case "$1" in
start)
 ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
 /sbin/route add -host $VIP dev lo:0 
 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
 echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
 echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
 echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
 sysctl -p >/dev/null 2>&1
 echo "RealServer Start OK"
 ;;
stop)
 ifconfig lo:0 down
 route del $VIP >/dev/null 2>&1 
 echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
 echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
 echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
 echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
 echo "RealServer Stoped"
 ;;
*)
 echo "Usage: $0 {start|stop}"
 exit 1
esac
 
exit 0

在/usr/local/src/目录下,给脚本可执行权限:[root@centos212 ~]# chmod -R 755 /usr/local/src/realserver.sh

按照上述结构图,从右往左逐个启动组件:先启动mysql,接着启动mycat,而后启动realserver.sh,再启动keepalived。咱们来看下负载均衡效果

Mycat - 高可用与负载均衡实现,满满的干货!

 

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。

 

负载均衡效果咱们能够经过ipvsadm -l命令来查看,具体体如今ActiveConn和InActConn值,ActiveConn是活动链接数,也就是tcp链接状态的ESTABLISHED,而InActConn是指除了ESTABLISHED之外的,全部的其它状态的tcp链接。由于./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB -e 'select @@hostname'是瞬时的,这个链接就归为InActConn,若是咱们想测试ActiveConn,咱们能够用./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB,其实与咱们平时操做mysql是同样的。从上图中能够看出,是达到了负载均衡效果的,192.168.1.110:8066与192.168.1.212:8066轮着来处理。

可能会有人对上图中./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB -e 'select @@hostname'的返回值有疑问:为何老是centos211? 这个sql其实就是查询mysql的主机名,注意是mysql服务器的主机名,不是mycat的主机名!sql最终的执行者是mysql! 而咱们知道mycat对mysql作了读写分离,也就是说./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB -e 'select @@hostname'始终会在mysql slave上执行,而咱们的mysql slave的ip是192.168.1.211,其hostname是centos211,因此看到的hostname老是centos211。

总结

一、不少时候咱们都只须要实现mycat的高可用,而不须要实现mycat的负载均衡;组件越多,越容易出错,也更难以维护;没有一成不变的最优方案,只有在合适时机的最佳方案;

二、keepalived的做用,有没有lvs,keepalived启动的做用是有所区别的。没有lvs时,keepalived负责vip的映射与转移、mycat的存活检测;有lvs时,Keepalived负责vip的映射与转移、RealServer的健康状态检查。无论有没有lvs,keepalived都会负责VIP的映射与转移,实现master和slave主机之间failover,达到高可用目的;

三、各个组件的职责都很明显,mysql负责sql的执行,mycat负责mysql的读写分离与高可用,lvs负责mycat的负载均衡与高可用,keepalived负责vip相关工做以及lvs的高可用。各个组件的角色弄清楚了,搭建起来也就不难了;

四、《Mycat权威指南》中采用haproxy + keepalived实现mycat的高可用和负载均衡,我就再也不重复讲了,有兴趣的能够去实践一把;另外留个疑问:nginx可不可实现mycat的负载均衡?

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。

加群直通车:854630135

相关文章
相关标签/搜索