LVS+Keepalived实现DBProxy的高可用

背景

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

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

1)LVS是什么

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

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

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

2)LVS模式

这里详细介绍DR和NAT模式

  • DR:直接路由模式,DR 模式下需要 LVS 和RS绑定同一个 VIP(RS 通过将 VIP 绑定在 loopback 实现)。
    LVS接收请求,由真实提供服务的服务器(RealServer, RS)直接返回给用户,返回的时候不经过LVS。即一个请求过来时,LVS只需要将网络帧的MAC地址修改为某一台RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变。RS收到LVS转发来的包时,链路层发现MAC是自己的,到上面的网络层,发现IP也是自己的,于是这个包被合法地接收,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即用户的IP)返回即可,不再经过LVS。

        特性:
           ①:调度服务器(director server)只接收client请求和转发到realserver,realserver再回应client,不需要在经过调度服务器,效率高。
           ②:不支持端口映射和跨域LAN。
  • NAT:网络地址转换,网络数据包的进出都要经过LVS的处理,LVS物理IP做为RS的网关。
    NAT(Network 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的存在。

            特性:
               ①:调度服务器(director server)接收client请求和转发到realserver,realserver再回应调度服务器,调度服务器再回应client, 调度服务器会成为瓶颈,效率低。
               ②:realserver和director server处于同一网络,仅于director server通讯,并且网络需要指向director server。
               ③:director server支持端口映射,可以将客户端请求的端口映射到realserver的另一个端口,DR模式不行。原因是NAT响应需要经过director server,DR则直接和客户端响应。

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

 3)调度算法

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

固定调度算法:rr,wrr,dh,sh

动态调度算法:wlc,lc,lblc,lblcr,sed,nq

算法

说明

rr

轮询算法,它将请求依次分配给不同的rs节点,也就是RS节点中均摊分配。这种算法简单,但只适合于RS节点处理性能差不多的情况

wrr

加权轮训调度,它将依据不同RS的权值分配任务。权值较高的RS将优先获得任务,并且分配到的连接数将比权值低的RS更多。相同权值的RS得到相同数目的连接数。

wlc

加权最小连接数调度,假设各台RS的全职依次为Wi,当前tcp连接数依次为Ti,依次去Ti/Wi为最小的RS作为下一个分配的RS

dh

目的地址哈希调度(destination hashing)以目的地址为关键字查找一个静态hash表来获得需要的RS

sh

源地址哈希调度(source hashing)以源地址为关键字查找一个静态hash表来获得需要的RS

lc

最小连接数调度(least-connection),IPVS表存储了所有活动的连接。LB会比较将连接请求发送到当前连接最少的RS.

lblc

基于地址的最小连接数调度(locality-based least-connection):将来自同一个目的地址的请求分配给同一台RS,此时这台服务器是尚未满负荷的。否则就将这个请求分配给连接数最小的RS,并以它作为下一次分配的首先考虑。

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

LVS+DBProxy

环境:

LVS的模式是DR,调度算法是wlc。 
系统:Ubuntu 16.04
director server :192.168.200.2
real server     :  192.168.200.10/12 已经装上了DBProxy,3309是管理接口,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去响应客户端(需要设置一个路由)。

设置: 

1)director 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(权重)

复制代码
添加真实服务器,-g:DR直接路由模式,-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   
复制代码

保存LVS:save

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

2)real 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
复制代码

3)LVS设置,使用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的相关命令步骤上面已经大致讲完,上面的设置都是临时的,重启之后都会无效,这里可以编写一个启动脚本:

1)Director Server:directorserver

复制代码
#!/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

2)Real Server:realserver

复制代码
#!/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和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当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区域里)引用。通过脚本做一些相关操作:邮件发送、数据操作等。如下面的配置样本

 View Code

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

性能测试说明

通过上面的说明,大致清楚了数据库的访问方式:先读取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实现负载均衡

posted on 2019-08-14 14:14  ExplorerMan  阅读(170)  评论(0编辑  收藏  举报

导航