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(真實服務器) $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區域里)引用。通過腳本做一些相關操作:郵件發送、數據操作等。如下面的配置樣本

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

    }

}
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實現負載均衡

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM