LVS+Keepalived负载均衡实践与心得补遗

Stella981
• 阅读 308

一.实践背景,分析:

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

LVS+Keepalived负载均衡实践与心得补遗

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

LVS+Keepalived负载均衡实践与心得补遗

如此一来避免了数据库单一节点故障的问题,针对Mysql来说,主主复制若出现故障,恢复步骤较主从复制繁琐。但是出于DB服务器系统本身的负载和性能考虑,图上该架构性能较优。

二.搭建环境:

1.下载keepalived和lvs(ipvsadm)源码包,编译安装,此处不赘述详细过程,仅提供经测试有效的配置文件,

首先是在两个LVS节点上都要部署的keepalived和lvs服务:

/etc/keepalived/keepalived.conf:

! Configuration File for keepalived

global_defs {
    router_id LVS_2  # 设置lvs的id,在一个网络内应该是唯一的
}

#vrrp_sync_group test_group {
#group {
#  VI_1
#}
#}

vrrp_instance VI_1 {
    state BACKUP   #指定Keepalived的角色,MASTER为主,BACKUP为备
    interface eth0  #虚拟ip所在网
 #   lvs_sync_daemon_interface eth0
    virtual_router_id 51  #虚拟路由编号,主备要一致
    priority 50  #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
    advert_int 1  #检查间隔,默认为1s
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.7.247/24  #定义虚拟IP(VIP)为10.0.7.247,可多设,每行一个
    }
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 10.0.7.247 80 {
    delay_loop 6 # 设置健康检查时间,单位是秒
    lb_algo wlc # 设置负载调度的算法为wlc 基于权重的调度算法
    #lb_algo wrr # 设置负载调度的算法为wrr 加权轮询调度算法
   # lb_algo rr # 设置负载调度的算法为wrr 轮询调度算法
    lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式,该处使用直接路由模式DR
    nat_mask 255.255.255.0
   # persistence_timeout 20 会话保持时间   (为了实验效果可以注释掉该选项)
    protocol TCP

  real_server 10.0.7.211 80 {  # 指定real server1的IP地址
        weight 60   # 配置节点权值,数字越大权重越高
        TCP_CHECK {
        connect_timeout 20
        nb_get_retry 3
        #delay_before_retry 3
        connect_port 80
        }
    }
  real_server 10.0.7.29 80 {  # 指定real server2的IP地址
        weight 40  # 配置节点权值,数字越大权重越高
        TCP_CHECK {
        connect_timeout 20
        nb_get_retry 3
      # delay_before_retry 3
        connect_port 80
        }
     }
 }

/etc/init.d/lvs_server脚本(该脚本可以放置在/etc/init.d目录下,配置为系统服务,方便控制):

#!/bin/bash
#把一下内容保存成:lvs_server
#并放置在/etc/init.d目录下
#如果想启动LVS Server执行:/etc/init.d/lvs_server start
#如果想停止LVS Server执行:/etc/init.d/lvs_server stop
#如果想重启LVS Server执行:/etc/init.d/lvs_server restart
#/sbin/ipvsadm 需要根据实际安装路径修改


VIP=10.0.7.247 #虚拟IP,更具具体情况而变
#有几个输入几个,与下面的配置对应,同时必须与KeepAlived.config配置对应
RIP1=10.0.7.211 #实际的服务器IP
RIP2=10.0.7.29 #实际的服务器IP
. /etc/rc.d/init.d/functions # 如果提示权限不够,那么先在命令行执行: chmod 777 /etc/rc.d/init.d/functions
case "$1" in

start)
        echo "启动LVS服务器"
          #设置虚拟IP和同步参数
          /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up
          echo "1" >/proc/sys/net/ipv4/ip_forward
          #清空 IPVS的内存数据
          /sbin/ipvsadm -C


          #开启WEB 80 端口服务,并指向RIP1和RIP2的服务器
          /sbin/ipvsadm -A -t $VIP:80 -s wlc
          /sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -g -w 60
          /sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -g -w 40
          #运行LVS
          /sbin/ipvsadm -ln
          ;;
stop)
       echo "关闭LVS服务器"
       echo "0" >/proc/sys/net/ipv4/ip_forward
       /sbin/ipvsadm -C
       /sbin/ifconfig eth0:0 down
       ;;

restart)
       echo "关闭LVS服务器"
       echo "0" >/proc/sys/net/ipv4/ip_forward
       /sbin/ipvsadm -C
       /sbin/ifconfig eth0:0 down

      echo "启动LVS服务器"
      #设置虚拟IP和同步参数
      /sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.0 up
      echo "1" >/proc/sys/net/ipv4/ip_forward
      #清空 IPVS的内存数据
      /sbin/ipvsadm -C

      #设置LVS
      #开启WEB 80 端口服务,并指向RIP1和RIP2的服务器
      /sbin/ipvsadm -A -t $VIP:80 -s wlc
      /sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -g -w 60
      /sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -g -w 40
      #运行LVS
      /sbin/ipvsadm -ln
      ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac

2.然后是部署在两台真实服务器real_server(这里由于架构拓扑上lvs直接和web服务端连通,所以此处的真实服务器角色是两个WEB SERVER节点)上的realserver脚本:

/etc/init.d/realserver,该脚本主要作用是用于真实服务器realserver与虚拟IP,即VIP通讯,转发数据包,具体底层网络原理可查阅相关文档

#!/bin/bash
#把一下内容保存成:real_server
#并放置在root目录下
#如果想启动real Server执行:/root/real_server start
#如果想停止real Server执行:/root/real_server stop

CLUSTER_VIP=10.0.7.247 #虚拟IP,更具具体情况而变
. /etc/rc.d/init.d/functions # 如果提示权限不够,那么先在命令行执行: chmod 777 /etc/rc.d/init.d/fu
nctionscase "$1" in
start)
       /sbin/ifconfig lo:0 $CLUSTER_VIP netmask 255.255.255.255 broadcast $CLUSTER_VIP
       /sbin/route add -host $CLUSTER_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 "真实服务器启动....."
       ;;
stop)
       /sbin/ifconfig lo:0 down
       /sbin/route del $CLUSTER_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 "真实服务器停止....."
       ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac

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的性能和数据结构等根本方面去优化,如果根本问题没有得到解决,那也只能是治标不治本,代码质量最关键 (成功甩锅,逃)。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这