LVS+Keepalived实现DBProxy的高可用

背景       在上一篇文章美团点评DBProxy读写分离使用说明实现了读写分离但在最后提了二个问题一是代理不管MySQL主从的复制状态二是DBProxy本身是一个单点的存在。对于第一个可以通过自己定义...

背景

      在上一篇文章美团点评DBProxy读写分离使用说明实现了读写分离但在最后提了二个问题一是代理不管MySQL主从的复制状态二是DBProxy本身是一个单点的存在。对于第一个可以通过自己定义的检测规则进行操作Admin接口实现主从状态异常的处理。而对于第二个问题需要再起一个DBProxy来防止单点故障本文通过介绍LVS来实现DBProxy的负载均衡和高可用。MySQL的架构如下

attachments-2018-07-I5eBBlcY5b59ed27c0507.png

LVS基础

http://www.linuxvirtualserver.org/zh/lvs1.html

http://www.linuxvirtualserver.org/zh/lvs2.html

http://www.linuxvirtualserver.org/zh/lvs3.html

http://www.linuxvirtualserver.org/zh/lvs4.html

1LVS是什么

LVS是Linux Virtual Server的简称也就是Linux虚拟服务器。主要用于服务器集群的负载均衡它是四层负载均衡建立在OSI模型的第四层——传输层之上传输层上有我们熟悉的 TCP/UDP。转发主要通过修改IP地址NAT 模式、修改目标 MACDR 模式来实现。它工作在网络层可以实现高性能高可用的服务器集群技术可把许多低性能的服务器组合在一起形成一个超级服务器。配置非常简单且有多种负载均衡的方法。即使在集群的服务器中某台服务器无法正常工作也不影响整体效果。另外可扩展性也非常好。LVS的体系结构如下

attachments-2018-07-v0beUkb75b59ed47b4089.png

1最前端的负载均衡层用Load Balancer表示用于负载均衡调度。LVS
2中间的服务器集群层用Server Array表示用于存放真实服务器。(DBProxy)
3最底端的数据共享存储层用Shared Storage表示(MySQL)

在用户看来所有的内部应用都是透明的用户只是在使用一个虚拟服务器提供的高性能服务。

2LVS模式

这里详细介绍DR和NAT模式

  • DR直接路由模式DR 模式下需要 LVS 和RS绑定同一个 VIPRS 通过将 VIP 绑定在 loopback 实现。
    LVS接收请求由真实提供服务的服务器RealServer, RS直接返回给用户返回的时候不经过LVS。即一个请求过来时LVS只需要将网络帧的MAC地址修改为某一台RS的MAC该包就会被转发到相应的RS处理注意此时的源IP和目标IP都没变。RS收到LVS转发来的包时链路层发现MAC是自己的到上面的网络层发现IP也是自己的于是这个包被合法地接收RS感知不到前面有LVS的存在。而当RS返回响应时只要直接向源IP即用户的IP返回即可不再经过LVS。
  • attachments-2018-07-jOhFhJ7U5b59ed700b5be.jpg
  • 特性
           ①调度服务器director server只接收client请求和转发到realserverrealserver再回应client不需要在经过调度服务器效率高。
           ②不支持端口映射和跨域LAN。
    • NAT网络地址转换网络数据包的进出都要经过LVS的处理LVS物理IP做为RS的网关。
      NATNetwork Address Translation是一种外网和内网地址映射的技术。NAT模式下网络数据包的进出都要经过LVS的处理。LVS需要作为RS真实服务器的网关。当包到达LVS时LVS做目标地址转换DNAT将目标IP改为RS的IP。RS接收到包以后仿佛是客户端直接发给它的一样。RS处理完返回响应时源IP是RS IP目标IP是客户端的IP。这时RS的包通过网关LVS中转LVS会做源地址转换SNAT将包的源地址改为VIP这样这个包对客户端看起来就仿佛是LVS直接返回给它的。客户端无法感知到后端RS的存在。
    • attachments-2018-07-uG71SMUy5b59ed8b96ebe.jpg
    •  特性
                     ①调度服务器director server接收client请求和转发到realserverrealserver再回应调度服务器调度服务器再回应client 调度服务器会成为瓶颈效率低。
                     ②realserver和director server处于同一网络仅于director server通讯并且网络需要指向director server。
                     ③director server支持端口映射可以将客户端请求的端口映射到realserver的另一个端口DR模式不行。原因是NAT响应需要经过director serverDR则直接和客户端响应。

      • TUNNELIP隧道模式主要用于RS不同一个地点的网络支持跨域LAN。
      • FULL-NAT

       3调度算法

      LVS的调度算法决定了如何在集群节点之间分布工作负荷。当director调度器收到来自客户端访问VIP的上的集群服务的入站请求时director调度器必须决定哪个集群节点应该处理请求。Director调度器用的调度方法基本分为两类 

      固定调度算法rrwrrdhsh

      动态调度算法wlclclblclblcr,sed,nq

      attachments-2018-07-EyH8B3l65b59ee371398b.png

      LVS更多的相关知识可以见官网说明下面开始部署测试。

      LVS+DBProxy

      环境

      LVS的模式是DR调度算法是wlc。 
      系统Ubuntu 16.04
      director server 192.168.200.2
      real server     :  192.168.200.10/12 已经装上了DBProxy3309是管理接口3308是数据访问接口
      VIP             :  192.168.200.1

      内核已集成ipvs模块只需在DS服务器上安装管理工具

      apt-get install ipvsadm 

      知识点说明

      在LVS的DR模式下从上面图中也可以看到调度服务器DS和真实服务器RS都绑定了VIP请求过来如何让DS来响应请求RS不响应这时需要获取mac地址在第2层进行通讯和DS来绑定只和DS来响应。通过系统参数arp_ignore(1)限制RS不去接收请求。接着DS收到请求之后需要把请求发给RS服务器这时RS服务器需要通过系统参数arp_announce(2)来隐藏其接收的接口(物理IP所在网卡)不回应让其回环地址lo去响应客户端需要设置一个路由。

      设置 

      1director server设置临时

      在任意一个网卡(eth1:0)上添加vip广播地址设置成vip子网掩码4个255用于对外提供服务

      ifconfig eth1:0 192.168.200.1 broadcast 192.168.200.1 netmask 255.255.255.255 up


      添加路由从指定的网卡路由

      route add -host 192.168.200.1 dev eth1:0


      启用系统的包转发功能echo "1">/proc/sys/net/ipv4/ip_forward查看路由信息

      root@LVS-Director:~# route

      Kernel IP routing table

      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

      default         sfgw.host.dxy   0.0.0.0         UG    0      0        0 eth1

      192.168.200.0   *               255.255.255.0   U     0      0        0 eth1

      192.168.200.1   *               255.255.255.255 UH    0      0        0 eth1

      查看LVS信息ipvsadm -ln

      root@LVS-Director:~# ipvsadm -ln

      IP Virtual Server version 1.2.1 (size=4096)

      Prot LocalAddress:Port Scheduler Flags

        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

      InActConn 指非活跃连接数我们将处于 TCP ESTABLISH 状态以外的连接都称为不活跃连接。例如处于 SYN_RECV 状态的连接处于 TIME_WAIT 状态的连接等。

      ActiveConn指活动连接数

      Weight权重


      添加虚拟服务 ipvsadm -A(添加虚拟服务器) -t(处理tcp) $vip:port(虚拟IP:端口) -s wlc(调度算法)


      添加一个通过虚拟IP 3308端口的tcp服务wlc的调度算法
      root@LVS-Director:~# ipvsadm -A -t 192.168.200.1:3308 -s wlc
      root@LVS-Director:~# ipvsadm -L -n
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc

      添加真实服务器ipvsadm -a(添加真实服务器) -t(处理tcp) vip:port(IP:)g(LVS)r()vip:port(真实IP:端口)−g(LVS模式)−r(真实服务器)realserver(真实服务器IP) -w 1(权重)


      添加真实服务器-gDR直接路由模式-w权重
      root@LVS-Director:~# ipvsadm -a -t 192.168.200.1:3308 -g -r 192.168.200.10 -w 1  #真实服务器1
      root@LVS-Director:~# ipvsadm -a -t 192.168.200.1:3308 -g -r 192.168.200.12 -w 2  #真实服务器2
      root@LVS-Director:~# ipvsadm -L -n
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc
        -> 192.168.200.10:3308          Route   1      0          0         
        -> 192.168.200.12:3308          Route   2      0          0   

      保存LVSsave

      root@LVS-Director:~# /etc/init.d/ipvsadm save
       * Saving IPVS configuration...                                                                                                                            [ OK ] 

      2real server设置临时


      修改系统参数
      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 
      
      回环地址lo设置vip广播地址设置成vip子网掩码设置成4个255和DR的VIP保持通讯。
      ifconfig lo:0 192.168.200.1 broadcast 192.168.200.1 netmask 255.255.255.255 up
      
      添加路由从指定的网卡路由
      route add -host 192.168.200.1 dev lo:0
      
      root@LVS-RS1:~# route
      Kernel IP routing table
      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
      default         192.168.200.254 0.0.0.0         UG    0      0        0 eth0
      192.168.200.0   *               255.255.255.0   U     0      0        0 eth0
      192.168.200.1   *               255.255.255.255 UH    0      0        0 lo

      3LVS设置使用ipvsadm来设置管理。


      ipvsadm v1.28 2015/02/09 (compiled with popt and IPVS v1.2.1)
      Usage:用法
      #添加/修改一个虚拟服务包括协议tcp、udp...调度算法超时等。 ipvsadm
      -A|E virtual-service [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
      #删除一条虚拟服务 ipvsadm
      -D virtual-service
      #清除整个虚拟服务器表中的所有记录  ipvsadm
      -C
      #恢复虚拟服务器规则 ipvsadm
      -R
      #保存虚拟服务器规则 ipvsadm
      -S [-n]
      #添加/修改真实服务器包括LVS模式、权重、超时等 ipvsadm
      -a|e virtual-service -r server-address [options]
      #删除真实服务器 ipvsadm
      -d virtual-service -r server-address
      #显示虚拟服务器列表 ipvsadm
      -L|l [virtual-service] [options]
      #虚拟服务表计数器清零  ipvsadm
      -Z [virtual-service]
      #设置连接超时值 ipvsadm
      --set tcp tcpfin udp
      #启动同步守护进程。在这个功能上也可以采keepalived 的VRRP 功能。  ipvsadm
      --start-daemon state [--mcast-interface interface] [--syncid sid]
      #关闭守护进程 ipvsadm
      --stop-daemon state ipvsadm -h Commands: Either long or short options are allowed. --add-service -A add virtual service with options #添加虚拟服务器 --edit-service -E edit virtual service with options #修改虚拟服务器 --delete-service -D delete virtual service #删除虚拟服务器 --clear -C clear the whole table #清除虚拟服务器规则 --restore -R restore rules from stdin #还原虚拟服务器规则 --save -S save rules to stdout #保存虚拟服务器规则 --add-server -a add real server with options #添加真实服务器 --edit-server -e edit real server with options #修改真实服务器 --delete-server -d delete real server #删除真是服务器 --list -L|-l list the table #显示虚拟服务器列表 --zero -Z zero counters in a service or all services #虚拟服务表计数器清零清空当前的连接数量等 --set tcp tcpfin udp set connection timeout values #连接超时 --start-daemon start connection sync daemon #开启守护进程 --stop-daemon stop connection sync daemon #关闭守护进程 --help -h display this help message virtual-service: --tcp-service|-t service-address service-address is host[:port] #虚拟服务器提供的是tcp 的服务 --udp-service|-u service-address service-address is host[:port] #虚拟服务器提供的是udp 的服务 --sctp-service service-address service-address is host[:port] #虚拟服务器提供的时sctp流控制传输协议的服务 --fwmark-service|-f fwmark fwmark is an integer greater than zero #经过iptables 标记过的服务类型 Options: --ipv6 -6 fwmark entry uses IPv6 #使用ipv6 --scheduler -s scheduler one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq, #调度算法默认是使用wlc the default scheduler is wlc. --pe engine alternate persistence engine may be sip, not set by default. --persistent -p [timeout] persistent service #持久稳固的服务。这个选项的意思是来自同一个客户的多次请求将被同一台真实的服务器处理。timeout 的默认值为300 秒   --netmask -M netmask persistent granularity mask --real-server -r server-address server-address is host (and port) #真实服务器地址和端口 --gatewaying -g gatewaying (direct routing) (default) #LVS直接路由模式DR默认。 --ipip -i ipip encapsulation (tunneling) #LVS 隧道模式 --masquerading -m masquerading (NAT) #LVS NAT模式 --weight -w weight capacity of real server #真实服务器权重 --u-threshold -x uthreshold upper threshold of connections #最大连接 --l-threshold -y lthreshold lower threshold of connections #最小连接 --mcast-interface interface multicast interface for connection sync --syncid sid syncid for connection sync (default=255) --connection -c output of current IPVS connections #显示LVS 目前的连接如ipvsadm -L -c  --timeout output of timeout (tcp tcpfin udp) #显示tcp tcpfin udp 的timeout 值 如ipvsadm -L --timeout  --daemon output of daemon information #显示同步守护进程状态 --stats output of statistics information #显示统计信息统计自该条转发规则生效以来的包    --rate output of rate information #显示速率信息 --exact expand numbers (display exact values) --thresholds output of thresholds information --persistent-conn output of persistent connection info --nosort disable sorting output of service/server entries --sort does nothing, for backwards compatibility #对虚拟服务器和真实服务器排序输出  --ops -o one-packet scheduling --numeric -n numeric output of addresses and ports #输出IP 地址和端口的数字形式   --sched-flags -b flags scheduler flags (comma-separated)

      监控相关状态

      --stats是统计自该条转发规则生效以来的信息 


      root@LVS-Director:~# ipvsadm -l --stats
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
        -> RemoteAddress:Port
      TCP  192.168.200.1:3308                  4       42        0     2711        0
        -> 192.168.200.10:3308                 1       11        0      680        0
        -> 192.168.200.12:3308                 3       31        0     2031        0
      
      Conns    (connections scheduled)  已经转发过的连接数  
      InPkts   (incoming packets)       入包个数  
      OutPkts  (outgoing packets)       出包个数  
      InBytes  (incoming bytes)         入流量字节    
      OutBytes (outgoing bytes)         出流量字节

      --rate显示速率信息


      root@LVS-Director:~# ipvsadm -l --rate
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port                 CPS    InPPS   OutPPS    InBPS   OutBPS
        -> RemoteAddress:Port
      TCP  192.168.200.1:3308                  0        0        0        0        0
        -> 192.168.200.10:3308                 0        0        0        0        0
        -> 192.168.200.12:3308                 0        0        0        0        0
      
      CPS      (current connection rate)   每秒连接数  
      InPPS    (current in packet rate)    每秒的入包个数  
      OutPPS   (current out packet rate)   每秒的出包个数  
      InBPS    (current in byte rate)      每秒入流量字节  
      OutBPS   (current out byte rate)      每秒入流量字节

      现在通过访问192.168.200.1的3308端口直接就可以按照调度算法进行访问下面真实服务器的端口服务了。

      4测试


      访问
      [zhoujy@localhost ~]$ mysql -usbtest -psbtest -P3308 -h192.168.200.1
      ...
      sbtest@192.168.200.1 : (none) 02:35:54>show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | sbtest             |
      +--------------------+
      
      关闭200.10的DBProxy看看能否继续访问
      root@LVS-RS1:/usr/local/mysql-proxy# ./bin/mysql-proxyd test_proxy stop
      OK: MySQL-Proxy of test_proxy is stopped
      
      访问
      root@LVS-RS2:~# mysql -usbtest -psbtest -P3308 -h127.0.0.1
      ...
      mysql> show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | sbtest             |
      +--------------------+
      2 rows in set (0.00 sec)

      从上面看到关闭了一台DBProxy可以继续访问。这样DBProxy的单点故障的问题解决了

      启动脚本

      开启LVS的相关命令步骤上面已经大致讲完上面的设置都是临时的重启之后都会无效这里可以编写一个启动脚本

      1Director Serverdirectorserver


      #!/bin/bash
      
      VIP=192.168.200.1
      RIP1=192.168.200.10
      RIP2=192.168.200.12
      
      case "$1" in
        start)
          echo "开始启动LVS Director Server..."
          ifconfig eth1:0 $VIP broadcast $VIP netmask 255.255.255.255 up
          route add -host $VIP dev eth1:0
          echo "1">/proc/sys/net/ipv4/ip_forward
          sysctl -p >/dev/null 2>&1
          ipvsadm -C
          ipvsadm -A -t $VIP:3308 -s rr
          ipvsadm -a -t $VIP:3308 -r $RIP1 -g -w 1
          ipvsadm -a -t $VIP:3308 -r $RIP2 -g -w 2
          ipvsadm --save
          echo "开启成功"
          ;;
        stop)
          echo "正在关闭LVS Director Server..."
          echo "0">/proc/sys/net/ipv4/ip_forward
          ipvsadm -C
          ifconfig eth1:0 down
          echo "关闭成功"
          ;;
        *)
          echo "用法$0 {start|stop}"
          exit 1
      esac

      使用

      /etc/init.d/directorserver start
      /etc/init.d/directorserver stop

      2Real Serverrealserver


      #!/bin/bash
      
      VIP=192.168.200.1
      
      case "$1" in
        start)
         echo "启动LVS Real Server..."
         ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
         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 "开启成功"
         ;;
        stop)
         echo "正在关闭LVS Real server"
         ifconfig lo:0 down
         echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
         echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
         echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
         echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
         echo "关闭成功"
         ;;
        *)
         echo "用法$0 {start|stop}"
         exit 1
      esac

      使用

      /etc/init.d/realserver start
      /etc/init.d/realserver stop

      上面通过LVS实现了RS的高可用然而LVS本身也是有单点的这个可以通过Keepalived来实现LVS的高可用下面来说明下Keepalived的相关说明。

      LVS+Keepalived+DBProxy

      1安装keepalived

      关于Keepalived的说明可以看官网keepalived工作原理和配置说明

      Keepalived是一个基于VRRP协议来实现的WEB 服务高可用方案可以利用其来避免单点故障。一个服务至少会有2台服务器运行Keepalived一台为主服务器MASTER一台为备份服务器BACKUP但是对外表现为一个虚拟IP主服务器会发送特定的消息给备份服务器当备份服务器收不到这个消息的时候即主服务器宕机的时候备份服务器就会接管虚拟IP继续提供服务从而保证了高可用性。其的工作原理

      keepalived是以VRRP协议为实现基础的VRRP全称Virtual Router Redundancy Protocol即虚拟路由冗余协议。虚拟路由冗余协议可以认为是实现路由器高可用的协议即将N台提供相同功能的路由器组成一个路由器组这个组里面有一个master和多个backupmaster上面有一个对外提供服务的vip该路由器所在局域网内其他机器的默认路由为该vipmaster会发组播当backup收不到vrrp包时就认为master宕掉了这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。keepalived主要有三个模块分别是core、check和vrrp。core模块为keepalived的核心负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。

      下载Keepalived

      wget http://www.keepalived.org/software/keepalived-1.3.5.tar.gz

      编译安装Keepalived(根据提示安装相关的依赖包):

      ./configure
      make
      make install

      安装成功


      root@LVS-Director:~# keepalived -h
      Usage: keepalived [OPTION...]
        -f, --use-file=FILE          Use the specified configuration file
        -P, --vrrp                   Only run with VRRP subsystem
        -C, --check                  Only run with Health-checker subsystem
        -l, --log-console            Log messages to local console
        -D, --log-detail             Detailed log messages
        -S, --log-facility=[0-7]     Set syslog facility to LOG_LOCAL[0-7]
        -X, --release-vips           Drop VIP on transition from signal.
        -V, --dont-release-vrrp      Don't remove VRRP VIPs and VROUTEs on daemon stop
        -I, --dont-release-ipvs      Don't remove IPVS topology on daemon stop
        -R, --dont-respawn           Don't respawn child processes
        -n, --dont-fork              Don't fork the daemon process
        -d, --dump-conf              Dump the configuration data
        -p, --pid=FILE               Use specified pidfile for parent process
        -r, --vrrp_pid=FILE          Use specified pidfile for VRRP child process
        -c, --checkers_pid=FILE      Use specified pidfile for checkers child process
        -a, --address-monitoring     Report all address additions/deletions notified via netlink
        -s, --namespace=NAME         Run in network namespace NAME (overrides config)
        -m, --core-dump              Produce core dump if terminate abnormally
        -M, --core-dump-pattern=PATN Also set /proc/sys/kernel/core_pattern to PATN (default 'core')
        -i, --config_id id           Skip any configuration lines beginning '@' that don't match id
        -v, --version                Display the version number
        -h, --help                   Display this help message

      编译可以参考http://www.cnblogs.com/tugeler/p/6621959.htmlhttp://xg2007524.blog.51cto.com/869106/1363643也可以直接apt-get install 安装。

      2)Keepalived配置

      在上面介绍了自己编写启动脚本启动LVS,通过Keepalived可以代替directorserver的启动脚本。要实现LVS的高可用,需要再起一台LVS服务器,通过Keepalived在2台LVS服务器上配置一个主和备来相互检测。如:启动一台IP为192.168.200.24(eth0)服务器,安装上ipvsadm和Keepalived。

      ① MASTER Keepalived配置(192.168.200.2,/etc/keepalived/keepalived.conf):


      ! Configuration File for keepalived
      
      #global_defs区域:主要是配置故障发生时的通知对象以及机器标识
      global_defs {
         notification_email {
           zjy@xxx.com
         }
         notification_email_from keepalived@smtp.dxy.cn
         smtp_server 192.168.200.254
         smtp_connect_timeout 30
      #设置lvs的id
         router_id LVS_Masterdata_M
      }
      
      #用来定义对外提供服务的VIP
      vrrp_instance VI_Master {
      #指定Keepalived的角色,MASTER为主,BACKUP为备
          state MASTER
      #HA检测设备
          interface eth1
      #虚拟路由编号,主备要一致    
          virtual_router_id 99
      #定义优先级,数字越大,优先级越高,主DR必须大于备用DR    
          priority 100
      #检查间隔,默认为1s,VRRP Multicast 广播周期秒数  
          advert_int 1
      #认证
          authentication {
              auth_type PASS
              auth_pass 1111
          }
      #定义vip,多个vip可换行添加
          virtual_ipaddress {
              192.168.200.1
          }
      #执行发送邮件给global_defs的配置
      smtp_alert } #director server 设置 virtual_server
      192.168.200.1 3308 { #每隔6秒查看realserver状态 delay_loop 6 #lvs调度算法 lb_algo wlc #lvs工作模式为DR(直接路由)模式 lb_kind DR #同一IP 的连接50秒内被分配到同一台realserver(测试时建议改为0) persistence_timeout 50 #用TCP监测realserver的状态 protocol TCP #realserver 设置 real_server 192.168.200.10 3308 { #定义权重 weight 3 TCP_CHECK { #连接超时时间 connect_timeout 3 #重连次数 nb_get_retry 3 #重试的间隔时间 delay_before_retry 3 #连接的后端端口 connect_port 3308 } } real_server 192.168.200.12 3308 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3308 } } }

      ② BACKUP Keepalived配置(192.168.200.24,/etc/keepalived/keepalived.conf): 


      ! Configuration File for keepalived
      
      #global_defs区域:主要是配置故障发生时的通知对象以及机器标识
      global_defs {
         notification_email {
           zjy@xxx.com
         }
         notification_email_from keepalived@smtp.dxy.cn
         smtp_server 192.168.200.254
         smtp_connect_timeout 30
      #设置lvs的id
         router_id LVS_Masterdata_S
      }
      
      #用来定义对外提供服务的VIP
      vrrp_instance VI_Slave {
      #指定Keepalived的角色,MASTER为主,BACKUP为备
          state BACKUP
      #HA检测设备
          interface eth0
      #虚拟路由编号,主备要一致    
          virtual_router_id 99
      #定义优先级,数字越大,优先级越高,主DR必须大于备用DR    
          priority 80
      #检查间隔,默认为1s,VRRP Multicast 广播周期秒数  
          advert_int 1
      #认证
          authentication {
              auth_type PASS
              auth_pass 1111
          }
      #定义vip,多个vip可换行添加
          virtual_ipaddress {
              192.168.200.1
          }
      #执行发送邮件给global_defs的配置
      smtp_alert } #director server 设置 virtual_server
      192.168.200.1 3308 { #每隔6秒查看realserver状态 delay_loop 6 #lvs调度算法 lb_algo wlc #lvs工作模式为DR(直接路由)模式 lb_kind DR #同一IP 的连接50秒内被分配到同一台realserver(测试时建议改为0) persistence_timeout 50 #用TCP监测realserver的状态 protocol TCP #realserver 设置 real_server 192.168.200.10 3308 { #定义权重 weight 3 TCP_CHECK { #连接超时时间 connect_timeout 3 #重连次数 nb_get_retry 3 #重试的间隔时间 delay_before_retry 3 #连接的后端端口 connect_port 3308 } } real_server 192.168.200.12 3308 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3308 } } }

      ③ 开启Keepalived

      /etc/init.d/keepalived start

      主Keepalived上的信息:


      #VIP已经绑定
      root@LVS-Director:~# ip add
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
          inet6 ::1/128 scope host 
             valid_lft forever preferred_lft forever
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 00:0c:29:64:69:45 brd ff:ff:ff:ff:ff:ff
          inet 172.16.109.128/24 brd 172.16.109.255 scope global eth0
             valid_lft forever preferred_lft forever
          inet6 fe80::20c:29ff:fe64:6945/64 scope link 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 00:0c:29:64:69:4f brd ff:ff:ff:ff:ff:ff
          inet 192.168.200.2/24 brd 192.168.200.255 scope global eth1
             valid_lft forever preferred_lft forever
          inet 192.168.200.1/32 scope global eth1
             valid_lft forever preferred_lft forever
          inet6 fe80::20c:29ff:fe64:694f/64 scope link 
             valid_lft forever preferred_lft forever
      
      #LVS相关信息被自动配置
      root@LVS-Director:~# ipvsadm -ln
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc persistent 50
        -> 192.168.200.10:3308          Route   3      0          0         
        -> 192.168.200.12:3308          Route   1      0          0      
       

      备Keepalived的信息:


      #VIP没有被配置,
      root@LVS-Director2:~# ip add
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
      13: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1
          link/ether 00:16:3e:24:60:11 brd ff:ff:ff:ff:ff:ff
          inet 192.168.200.24/24 brd 192.168.200.255 scope global eth0
             valid_lft forever preferred_lft forever
      
      #LVS相关信息被自动配置
      root@LVS-Director2:~# ipvsadm -ln
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc persistent 50
        -> 192.168.200.10:3308          Route   3      0          0         
        -> 192.168.200.12:3308          Route   1      0          0  

      director server 已经启动,然后通过上面的脚本启动real server。

      ④ 测试

      1,模拟RS1挂了,看LVS是否保证DBProxy的高可用:


      1:关闭RS1的DBProxy
      root@LVS-RS1:/usr/local/mysql-proxy# ./bin/mysql-proxyd masterdata_proxy stop
      OK: MySQL-Proxy of masterdata_proxy is stopped
      
      2:通过VIP连接DBProxy
      /Users/jinyizhou [16:07:17] ~$ mysql -usbtest -psbtest -P3308 -h192.168.200.1
      ...
      sbtest@192.168.200.1 : (none) 04:07:18>show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | sbtest             |
      +--------------------+
      2 rows in set (0.00 sec)
      
      3:查看LVS状态
      oot@LVS-Director:~# ipvsadm -ln
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc persistent 50
        -> 192.168.200.12:3308          Route   1      1          0   
      
      root@LVS-Director:~# ipvsadm -l --stats
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
        -> RemoteAddress:Port
      TCP  192.168.200.1:3308                  3       91        0     5616        0
        -> 192.168.200.12:3308                 3       91        0     5616        0   

      结果:关闭了RS1,服务还可以使用,所有的连接都被转到了RS2上。LVS保证了RS服务的HA。

      2,模拟LVS挂了,看Keepalived是否保证LVS的高可用:


      关闭MASTER Keepalived
      root@LVS-Director:~# /etc/init.d/keepalived stop
      [ ok ] Stopping keepalived (via systemctl): keepalived.service.
      
      VIP漂移了:
      root@LVS-Director:~# ip add
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
          inet6 ::1/128 scope host 
             valid_lft forever preferred_lft forever
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 00:0c:29:64:69:45 brd ff:ff:ff:ff:ff:ff
          inet 172.16.109.128/24 brd 172.16.109.255 scope global eth0
             valid_lft forever preferred_lft forever
          inet6 fe80::20c:29ff:fe64:6945/64 scope link 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 00:0c:29:64:69:4f brd ff:ff:ff:ff:ff:ff
          inet 192.168.200.2/24 brd 192.168.200.255 scope global eth1
             valid_lft forever preferred_lft forever
          inet6 fe80::20c:29ff:fe64:694f/64 scope link 
             valid_lft forever preferred_lft forever
      
      LVS也关闭了:
      root@LVS-Director:~# ipvsadm -ln
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      
      查看原先的BACKUP Keepalived:接管了VIP
      root@LVS-Director2:~# ip add
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
      13: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1
          link/ether 00:16:3e:24:60:11 brd ff:ff:ff:ff:ff:ff
          inet 192.168.200.24/24 brd 192.168.200.255 scope global eth0
             valid_lft forever preferred_lft forever
          inet 192.168.200.1/32 scope global eth0
             valid_lft forever preferred_lft forever
      
      LVS正常:
      root@rLVS-Director2:~# ipvsadm -ln
      IP Virtual Server version 1.2.1 (size=4096)
      Prot LocalAddress:Port Scheduler Flags
        -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
      TCP  192.168.200.1:3308 wlc persistent 50
        -> 192.168.200.10:3308          Route   3      1          0         
        -> 192.168.200.12:3308          Route   1      0          0      
      
      日志信息:切换成了MASTER
      Apr 24 16:16:14 LVS-Director2 Keepalived_vrrp[41092]: VRRP_Instance(VI_1) Transition to MASTER STATE
      Apr 24 16:16:15 LVS-Director2 Keepalived_vrrp[41092]: VRRP_Instance(VI_1) Entering MASTER STATE
      
      连接DBProxy:正常
      /Users/jinyizhou [16:26:13] ~$ mysql -usbtest -psbtest -P3308 -h192.168.200.1
      ...
      sbtest@192.168.200.1 : sbtest 04:26:16>select * from x;
      ...

      结果:关闭了MASTER Keepalived,服务还可以使用,所有的连接都被转到了BACKUP Keepalived上。Keepalived保证了LVS服务的HA。在使用Keepalived中,在vrrp_script的区域里定义脚本名字和脚本执行的间隔和脚本执行的优先级,在然后在实例(vrrp_instance区域里)引用。通过脚本做一些相关操作:邮件发送、数据操作等。如下面的配置样本

      vrrp_script vs_mysql_82 {


          script "/etc/keepalived/checkMySQL.py -h 127.0.0.1 -P 3309"


          interval 15


      }


      vrrp_instance VI_82 {


          state backup


          nopreempt


          interface eth1


          virtual_router_id 82


          priority 100


          advert_int 5


          authentication {


              auth_type PASS


              auth_pass 1111


          }


          track_script {


              vs_mysql_82


          }


          notify /etc/keepalived/notify.py


          virtual_ipaddress {


              192.168.11.110


          }


      }

      关于Keepalived的详细说明可以看官网或则http://www.cnblogs.com/pricks/p/3822232.html。到此,关于整个LVS+Keepalived+DBProxy已经介绍完毕,解决了美团点评DBProxy读写分离使用说明指出的第二个问题,实现了完整意义上的高可用。最后数据库的架构如下:MGW可以当成LVS,通过Keepalived来实现HA,最终实现跨机房读写分离。如下图所示的架构:

      attachments-2018-07-9M2okaA95b59f122b4c8d.png

      性能测试说明

      通过上面的说明,大致清楚了数据库的访问方式:先读取LVS提供的虚拟IP,根据其工作模式和调度算法连接到DBProxy,再通过DBProxy其工作方式进行转发,这样多了几层连接,对数据库的性能有多大影响?现在通过美团点评DBProxy读写分离使用说明中的测试方法进行测试:

      直连数据库:

      ./bin/sysbench --test=./share/sysbench/oltp_read_write.lua --mysql-host=192.168.200.202 --mysql-port=3306 --mysql-user=sbtest --mysql-password=sbtest --mysql-db=sbtest  --report-interval=10  --max-requests=0 --time=120 --threads=8 --tables=3  --table-size=500000 --skip-trx=on --db-ps-mode=disable --mysql-ignore-errors=1062  prepare/run/cleanup

      直连DBProxy:

      ./bin/sysbench --test=./share/sysbench/oltp_read_write.lua --mysql-host=192.168.200.10 --mysql-port=3308 --mysql-user=sbtest --mysql-password=sbtest --mysql-db=sbtest  --report-interval=10  --max-requests=0 --time=120 --threads=8 --tables=3  --table-size=500000 --skip-trx=on --db-ps-mode=disable --mysql-ignore-errors=1062 prepare/run/cleanup 

      通过LVS:

      ./bin/sysbench --test=./share/sysbench/oltp_read_write.lua --mysql-host=192.168.200.1 --mysql-port=3308 --mysql-user=sbtest --mysql-password=sbtest --mysql-db=sbtest  --report-interval=10  --max-requests=0 --time=120 --threads=8 --tables=3  --table-size=500000 --skip-trx=on --db-ps-mode=disable --mysql-ignore-errors=1062 prepare/run/cleanup 

      通过对8,16个线程的测试,发现通过LVS比直接DBProxy的QPS有近5%的提升。虽然访问数据库的链路加长了,但是通过LVS实现了负载均衡,使得多个DBproxy一起工作,提高了效率,性能没有比直连DBProxy差。当然,直连数据库的性能还是最高的。可以看美团点评DBProxy读写分离使用说明的性能测试说明。

      总结:

      通过这篇文章和美团点评DBProxy读写分离使用说明的一些基本介绍,了解了DBProxy读写分离功能的使用、性能和高可用的相关说明。关于更多DBProxy的说明可以参考手册说明。

      相关文档

      Keepalived介绍

      Keepalived原理

      keepalived工作原理和配置说明

      LVS介绍系列

      LVS+Keepalived实现负载均衡

       


  • 发表于 2018-07-26 23:50
  • 阅读 ( 52 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章