一.实践背景,分析:
公司研发的业务系统某个功能频繁出现数据库Mysql性能问题,导致系统使用卡顿,响应慢,且数据库所在服务器CPU负载居高不下,影响其他项目系统的正常数据库访问和使用。除去研发人员优化sql工作外,作为运维人员可以尝试对当前服务架构改造,目前架构大致如下:

如上图所示,当前压力都集中在数据库这一节点上,且代码上没有做读写分离,也一定程度上影响了系统性能。虽然有主从复制备库存在,但是当DB出现故障时,切换操作需要耗费一定的时间,实时性比较差。经过与研发同学讨论决定把架构改成如下:

如此一来避免了数据库单一节点故障的问题,针对Mysql来说,主主复制若出现故障,恢复步骤较主从复制繁琐。但是出于DB服务器系统本身的负载和性能考虑,图上该架构性能较优。
二.搭建环境:
1.下载keepalived和lvs(ipvsadm)源码包,编译安装,此处不赘述详细过程,仅提供经测试有效的配置文件,
首先是在两个LVS节点上都要部署的keepalived和lvs服务:
/etc/keepalived/keepalived.conf:
1! Configuration File for keepalived 2 3global_defs { 4 router_id LVS_2 # 设置lvs的id,在一个网络内应该是唯一的 5} 6 7#vrrp_sync_group test_group { 8#group { 9# VI_1 10#} 11#} 12 13vrrp_instance VI_1 { 14 state BACKUP #指定Keepalived的角色,MASTER为主,BACKUP为备 15 interface eth0 #虚拟ip所在网 16 # lvs_sync_daemon_interface eth0 17 virtual_router_id 51 #虚拟路由编号,主备要一致 18 priority 50 #定义优先级,数字越大,优先级越高,主DR必须大于备用DR 19 advert_int 1 #检查间隔,默认为1s 20 authentication { 21 auth_type PASS 22 auth_pass 1111 23 } 24 virtual_ipaddress { 25 10.0.7.247/24 #定义虚拟IP(VIP)为10.0.7.247,可多设,每行一个 26 } 27} 28# 定义对外提供服务的LVS的VIP以及port 29virtual_server 10.0.7.247 80 { 30 delay_loop 6 # 设置健康检查时间,单位是秒 31 lb_algo wlc # 设置负载调度的算法为wlc 基于权重的调度算法 32 #lb_algo wrr # 设置负载调度的算法为wrr 加权轮询调度算法 33 # lb_algo rr # 设置负载调度的算法为wrr 轮询调度算法 34 lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式,该处使用直接路由模式DR 35 nat_mask 255.255.255.0 36 # persistence_timeout 20 会话保持时间 (为了实验效果可以注释掉该选项) 37 protocol TCP 38 39 real_server 10.0.7.211 80 { # 指定real server1的IP地址 40 weight 60 # 配置节点权值,数字越大权重越高 41 TCP_CHECK { 42 connect_timeout 20 43 nb_get_retry 3 44 #delay_before_retry 3 45 connect_port 80 46 } 47 } 48 real_server 10.0.7.29 80 { # 指定real server2的IP地址 49 weight 40 # 配置节点权值,数字越大权重越高 50 TCP_CHECK { 51 connect_timeout 20 52 nb_get_retry 3 53 # delay_before_retry 3 54 connect_port 80 55 } 56 } 57 }
/etc/init.d/lvs_server脚本(该脚本可以放置在/etc/init.d目录下,配置为系统服务,方便控制):
1#!/bin/bash 2#把一下内容保存成:lvs_server 3#并放置在/etc/init.d目录下 4#如果想启动LVS Server执行:/etc/init.d/lvs_server start 5#如果想停止LVS Server执行:/etc/init.d/lvs_server stop 6#如果想重启LVS Server执行:/etc/init.d/lvs_server restart 7#/sbin/ipvsadm 需要根据实际安装路径修改 8 9 10VIP=10.0.7.247 #虚拟IP,更具具体情况而变 11#有几个输入几个,与下面的配置对应,同时必须与KeepAlived.config配置对应 12RIP1=10.0.7.211 #实际的服务器IP 13RIP2=10.0.7.29 #实际的服务器IP 14. /etc/rc.d/init.d/functions # 如果提示权限不够,那么先在命令行执行: chmod 777 /etc/rc.d/init.d/functions 15case "$1" in 16 17start) 18 echo "启动LVS服务器" 19 #设置虚拟IP和同步参数 20 /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up 21 echo "1" >/proc/sys/net/ipv4/ip_forward 22 #清空 IPVS的内存数据 23 /sbin/ipvsadm -C 24 25 26 #开启WEB 80 端口服务,并指向RIP1和RIP2的服务器 27 /sbin/ipvsadm -A -t $VIP:80 -s wlc 28 /sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -g -w 60 29 /sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -g -w 40 30 #运行LVS 31 /sbin/ipvsadm -ln 32 ;; 33stop) 34 echo "关闭LVS服务器" 35 echo "0" >/proc/sys/net/ipv4/ip_forward 36 /sbin/ipvsadm -C 37 /sbin/ifconfig eth0:0 down 38 ;; 39 40restart) 41 echo "关闭LVS服务器" 42 echo "0" >/proc/sys/net/ipv4/ip_forward 43 /sbin/ipvsadm -C 44 /sbin/ifconfig eth0:0 down 45 46 echo "启动LVS服务器" 47 #设置虚拟IP和同步参数 48 /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up 49 echo "1" >/proc/sys/net/ipv4/ip_forward 50 #清空 IPVS的内存数据 51 /sbin/ipvsadm -C 52 53 #设置LVS 54 #开启WEB 80 端口服务,并指向RIP1和RIP2的服务器 55 /sbin/ipvsadm -A -t $VIP:80 -s wlc 56 /sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -g -w 60 57 /sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -g -w 40 58 #运行LVS 59 /sbin/ipvsadm -ln 60 ;; 61*) 62 echo "Usage: $0 {start|stop}" 63 exit 1 64esac
2.然后是部署在两台真实服务器real_server(这里由于架构拓扑上lvs直接和web服务端连通,所以此处的真实服务器角色是两个WEB SERVER节点)上的realserver脚本:
/etc/init.d/realserver,该脚本主要作用是用于真实服务器realserver与虚拟IP,即VIP通讯,转发数据包,具体底层网络原理可查阅相关文档
1#!/bin/bash 2#把一下内容保存成:real_server 3#并放置在root目录下 4#如果想启动real Server执行:/root/real_server start 5#如果想停止real Server执行:/root/real_server stop 6 7CLUSTER_VIP=10.0.7.247 #虚拟IP,更具具体情况而变 8. /etc/rc.d/init.d/functions # 如果提示权限不够,那么先在命令行执行: chmod 777 /etc/rc.d/init.d/fu 9nctionscase "$1" in 10start) 11 /sbin/ifconfig lo:0 $CLUSTER_VIP netmask 255.255.255.255 broadcast $CLUSTER_VIP 12 /sbin/route add -host $CLUSTER_VIP dev lo:0 13 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore 14 echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce 15 echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore 16 echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce 17 sysctl -p >/dev/null 2>&1 18 echo "真实服务器启动....." 19 ;; 20stop) 21 /sbin/ifconfig lo:0 down 22 /sbin/route del $CLUSTER_VIP >/dev/null 2>&1 23 echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore 24 echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce 25 echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore 26 echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce 27 echo "真实服务器停止....." 28 ;; 29*) 30 echo "Usage: $0 {start|stop}" 31 exit 1 32esac
3.最后依次启动两个真实服务器realserver上的realserver脚本建立网卡子接口,并启动两个LVS服务器上的keepalived服务和lvs_server脚本即可。检查各服务器节点间防火墙放行规则,确保通讯成功。并在LVS服务器节点上可使用
while ((1));do ipvsadm -Ln;sleep 1;done
动态刷新查看lvs服务连接数的分发状态等信息,如果修改lvs分发算法和权重,需要同步修改所有节点的配置文件,并在测试时候观察实际连接数是否符合算法特征。
三.心得体会
1.当前公司使用的阿里云已经集成了收费的负载均衡功能,可以实时调整后端服务器访问权重,lvs分发所使用的算法,不需要再繁琐的专门分配单独服务器部署lvs系统,也算是带来了一定的便利性,用户可以根据实际需要选用。
2.关于Mysql和后端服务器节点之间的架构,考虑到灾后恢复的时效性,数据重建的便利性,性能负载的使用效率三个方面,上文描述中的选型不是最佳解决方案。包括如何分配数据库服务器资源出来做读写分离,使用主主复制还是主从复制几个问题,均有待后续研究和完善。
3.从测试后得出的结果来看,数据库分流确实一定程度上解决了数据库服务器本身的负载问题(包括CPU,磁盘IO),但是归根到底还是要从sql的性能和数据结构等根本方面去优化,如果根本问题没有得到解决,那也只能是治标不治本,代码质量最关键 (成功甩锅,逃)。