1. 程式人生 > >Cluster了解+LB{ LVS(四種模式)+ipvs+lvs持久連接 }

Cluster了解+LB{ LVS(四種模式)+ipvs+lvs持久連接 }

inpu 網卡 netmask pvs 交互 eas sch 用戶空間 bash

Cluster:
    系統擴展的兩種思路:
        scale up:向上擴展 -- 性能更好的主機,替換舊的主機
        scale out:橫向擴展 -- 添加服務器(但是服務是可以分開的,獨立的)

        cookie:服務器端生成一個cookie-id,發送給客戶端,客戶端每次訪問,都會將cookie發送給服務器端
        session:服務器端會比對cookie和seesion的對應情況(服務器內存中)

        實現 LB(負載均衡)-- 問題所在
            1、DNS:
                不要使用dns 去實現 LB,因為DNS 解析會緩存,所以效果很差
            
2、前端實現一個調度器: 如果請求和響應都通過 調度器,導致壓力很大。 集群類型: LB:負載均衡,均衡負載,調度到不同的服務器訪問資源(同一或不同資源) HA:高可用,提高冗余,服務器一直在線,一個down掉,其他服務器取而代之 HP:集中式的高性能服務器 不同於 分布式 平均無故障時間/(平均無故障時間 + 平均修復時間) -- 90% 95% 99% 99.9% 99.99% 系統: 可擴展性 可用性: 服務器是否隨時可用 容量: 系統運維:可用
---> 標準化 --- > 自動化 ****構建高可擴展性系統的重要原則:在系統內部盡量避免串行和交互 GLSB:Global Service Load Blancing SLB:Service Load Blancing 靜態內容的響應遠大於動態響應,動態服務器是無法緩存的,基於CDN的都是靜態服務器 緩存是KEY-value存儲,所以查詢緩存要快很多。但是如果數據過期了,查緩存時間就多了。 構建一個系統: 1、分層:每個功能一個層,每個服務器制作自己的事
2、分割:不同應用分割道不同服務器 3、分布式:無法分割的 分布式應用 分布式靜態資源 分布式數據和存儲 分布式計算 通過量: 容納量: 吞吐量:最大吞吐量 保證可接受容量的條件下,平均吞吐量。 LB 集群的實現: 後臺服務器具有全部的數據集 硬件實現: F5 BIG-IP Citrix NetScaler A10 軟件: LVS Haproxy nginx ats(apache traffic server) httpd(proxy模塊) varnish perlbal 基於工作的協議層次劃分: 傳輸層: LVS, haproxy(mode可以模擬tcp) 應用層:(反向代理) nginx -- 應用程序 haproxy -- 應用程序 ats perlbal 註意: LVS 依附於netfilter工作於內核,只需要 端口 對於應用程序,本身就需要一個套接字,而端口最多65535個,所以並發數最多65535個 監聽套接字 已連接套接字 網站並發連接數2-3w,pv量就達到千萬級別了 所以一般不會用到lvs 這種百萬級別的並發量的並發,而且一般這個級別的時候,可能用CDN了,不會直接到達服務器了。 LVS:工作在傳輸層的LB均衡器 工作於netfilter上的 LVS:Linux Virtual Server虛擬服務器,不是真正提供服務的 LVS也稱為---L4:4層路由, 根據請求報文的目標IP 和PORT 將其轉發後端主機集群中的某一臺(根據挑選算法) netfilter: PREROUTING ---> INPUT PREROUTING ---> FORWARD ---> POSTROUTING OUTPUT ---> POSTROUTING DNAT: PREROUTING上 在路由轉發之前,發現ip不是本機,就不會轉發了 LVS: 工作在INPUT 上,發現是集群服務(例如:某個端口作為集群服務),就強行改變,到POSTROUTING PREROUTING ---> INPUT --> POSTROUTING 在內核中工作 就不是服務 LVS: 用戶空間:ipvsadm命令行工具,用於管理集群服務, 增刪查改 內核空間:ipvs工作於內核中INPUT連上 內核編譯時加載的模塊: /boot/config-2.6.32-696.el6.x86_64 y:已經加載 m:可以手動在加載 支持的協議: TCP,UDP ,EST,AH_EXT,SCTP等 lvs arch: 調度器:director,dispatcher,balancer 後端:real server CIP VIP DIP RIP lvs 類型: lvs-nat lvs-dr(diretct routing) lvs-tun(隧道) lvs-fullnat lvs-nat: DIP,RIP:內網地址 VIP:外網 請求: CIP-VIP CIP-DIP CIP-RIP PREROUTING --> INPUT --> POSTROUTING 響應: RIP-CIP VIP-CIP PREROUTING --> FORWARD --> POSTROUTING 維持 NAT 會話表 多目標的DNAT(iptables):通過修改請求報文的目標IP地址(同時可能會修改目標端口)至挑選出的某RS 的RIP地址,實現轉發。 1、RS應該和DIP 應該使用私有網址,RS的網關指向DIP 2、請求和響應的報文 都要經由director轉發,極高負載場景中,direxctor會成為瓶頸 3、支持端口映射 4、RS 可以使用 windows,Linux等任意OS 5、RIP 和 DIP 必須在同一IP 網絡(加個路由,沒必要) lvs-dr:直接轉發 通過修改請求報文的目標MAC地址進行轉發的。 在網路上傳輸,經過路由和網關,sip dip是不會變的,但是mac是會變的。直到LAN D:DIP,VIP R:RIP,VIP D 通過arp廣播,獲取的是RS的mac地址,到達D,發現mac變為RS,在轉發到RS 1、保證前端路由器將目標IP 為VIP的請求報文發送給director 解決方案: 路由器跟D 綁定(但是D掛了,還得重新綁定) 修改RS 內核參數 2、RS的RIP 可以使用私有地址,可以使用公網地址 3、RS 和 D 必須在同一物理網絡中 4、請求報文 通過 D 調用,響應報文一定不能經過D 5、不支持端口映射:請求80,RS回應8080,就錯了被 6、RS可以大多數os 7、RS的網關不能指向DIP lvs-tun: 不修改請求報文的ip 首部,而是通過在原有的ip首部外面再封裝一個ip首部 響應:rs直接響應客戶端 cip ---> vip 再封裝一個ip首部(dip ---> rip) 1、RIP DIP VIP全部是公網 2、RS的網關 不能指向DIP 3、請求報文必須經由D 調度,響應報文不能D調度 4、不支持端口映射 5、RS的os 必須支持隧道功能 lvs-fullnat: ups:備用電源 D:同時修改原地址和目標地址 1、VIP是公網地址, rip和dip 是私網地址,二者無須同一網絡中 2、RS 接收到的請求報文的原地址為DIP,因此要響應給DIP 3、請求報文和響應報文都必須經由 D 4、支持端口映射 5、RS的os可以使用任意OS http:stateless無狀態 session保持機制: session綁定: 將來自於同一用戶的請求始終定向至同一個服務,維持一個會話表:追蹤同一個用戶 ip_hash:原地址hash,太粗糙,基於snet-ip訪問,就不行了 cookie綁定:session綁定上實現,LVS無法實現 但是某服務器宕機後,session就沒了 session集群 同步session信息 但是網絡中充斥大量的session,浪費帶寬。 session服務器 集中管理。session持久化的話,即便關機,也是沒關系的 --- redis 調度算法: cat /boot/config-2.6.32-696.el6.x86_64 靜態方法:僅根據算法本身進行調度,起點公平 RR:round robin輪詢 WRR:weight rr 權重 SH:source hash 原地址hsah, 實現session保持 -- 損壞負載均衡效果,來自同一IP的請求始終調度到同一服務器 DH:destation hash,類似:訪問同一個資源,會定向到同一個服務器(lvs無法實現url調度,只能ip和port,只是舉例說明) 同一個防火墻出去的,通過同一個防火墻進來。 動態方法:根據算法及各RS的當前負載狀態進行調度,結果公平 Overhead(當前負載)= LC:least connection,哪個服務器鏈接數最少,就調度到哪個 剛開始或者Overhead一樣:自上而下挑選 Overhead= active * 256 + inactive WLC:weight LC overhead = (active * 256 + inactive) / weight 缺陷: 如果計算後都一樣的值,這是從上往下選,但是正好,第一個負載很重 SED:最短期望延遲 初始連接高權重優先 (active+1)* 256 /weight 缺陷: 如果兩臺:weight=4,1 則來的都是在4 上 NQ:never queue sed的改進 第一輪均勻分配,後續SED LBLC:locality-Base LC :動態的DH 算法 大量緩存的時候,才會用 正向代理情形下的cache server 調度 LBLCR:帶復制的LBLC 解決LBLC負載不均衡,從負載重的復制到負載輕的 ipvs:的集群服務 1、一個ipvs主機可同時定義多個cluster service 2、一個cluster service 上至少有一個real server 定義時:指明lvs-type,以及lvs 調度算法 ipvsadm用法: 1、管理集群服務 ipvsadm -A|E -t|u|f service-address [-s scheduler] ipvsadm -D -t|u|f service-address service-address: tcp: -t ip:port udp: -u ip:port fwm: -f mark 防火墻標記,表示從這通過的 -s: 默認wlc 2、管理集群服務中的RS ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] [-x upper] [-y lower] ipvsadm -d -t|u|f service-address -r server-address server-address: ip[:port] -g:dr 模型。默認 -i:ipip tun模型 -m:nat 查看和清理: ipvsadm -C ipvsadm -L|l [options] -n:基於數字格式顯示地址和端口 -c:顯示ipvs連接 --stats: 入站 包個數,入站字節數 --rate:速率 pps:每妙包個數 Bps:字節數 --exact:顯示精確值 保存和重載: ipvsadm -R ipvsadm -S [-n] 置零計數器 ipvsadm -Z [-t|u|f service-address] 測試: nat: A --- > director eth0: vip eth1: dip web1 ---> eth0 rip1 web2 ---> eth0 rip2 1、iptables 關閉***或者清空**** 2、/etc/sysctl.conf 開啟轉發 3、規則: ipvsadm -A -t vip:80 -s rr ipvsadm -L -n ---查看 ipvsadm -a -t vip:80 -r rip1 -m ipvsadm -a -t vip:80 -r rip2 -m ipvsadm -L -n ---查看 ipvsadm -S > /etc/sysconfig/ipvsadm 保存 ipvsadm -C 清空 ipvsadm -L -n ---查看 ipvsadm -R 重載 修改: 修改算法: ipvsadm -E -t vip:80 -s sh 端口映射 ipvsadm -e -t vip:80 -r rip1:8080 -m 刪除: ipvsadm -d -t vip:80 -r rip1:8080 刪除集群: -D **web是https的話,每個服務器用同一個證書和私鑰 因為lvs是內核中工作,不會代替c和s 之間建立ssl會話 又因為訪問的是同一個域名,所以,需要同一個證書和秘鑰 短連接 和 長連接的問題** 有些特殊協議是不能lvs調度的 例如ftp:被動模式的ftp端口問題 dr: director: eht0 ---> dip eth0:0 ---> vip/32 web1: eth0 rip1 lo:0 vip web2: eth0 rip2 lo:0 vip arp廣播: annouce:是否通告別人 0:把自己所有的地址都告訴別人 1:盡量避免不要同不是同一網絡的 告訴別人 2:只能通過網卡出去 ignore:響不響應 0:有,就通知 1:從哪個接口進來,只有配置到該進來的接口 才響應 內核參數: # echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore # echo 2 > /proc/sys/net/ipv4/conf/all/arp_annouce # echo 1 > /proc/sys/net/ipv4/conf/INTERFACE/arp_ignore # echo 2 > /proc/sys/net/ipv4/conf/INTERFACE/arp_annouce 註意:INTERFACE為你的物理接口; # ifconfig lo:0 $vip netmask 255.255.255.255 broadcast $vip up # route add -host $vip dev lo:0 橋接: 目前的以太網都是通過交換機通信的 物理機的物理網卡,模擬成物理交換設備,虛擬機交換機與之相連 在同一網段中就可以通信 NAT:物理機上虛擬一個網卡 與 虛擬交換機建立關系,虛擬機網關指向虛擬網卡 經過物理網卡時,地址轉換為網卡的地址 HOST-Only:沒有nat 虛擬通道: vmnet2.... 不跟物理機通信 防火墻標記: -f 選項 fwm:用戶請求到達時,在 PREROUTING 設置標記 -j MARK --set-mark 10 ipvs: -A -f 10 將兩種不同的服務一起調度: 一臺服務器有如下服務: 一個443 一個80 打上同一個標記 如 10 ipvs規則直接用10 即可,否則每個都得定義成各自服務的集群 示例: ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99 ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99 ~]# ipvsadm -A -f 99 -s rr -p ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g lvs 持久連接: session保持: 綁定: 復制: 服務器: session綁定: 對多個共享同一組RS的服務,統一進行幫定(sh 算法無法解決) lvs persistence:lvs的持久連接 功能:無論ipvs使用何種調度方法,其都能事項將來自於同一個client的請求始終定向至第一次調度時挑選出的RS 持久連接模板:獨立於算法外:(第一次請求時,或者倒計時變為0了,使用定義的算法調度) sourceip -- RS -- timer -p選項,默認300秒 示例: ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99 ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99 ~]# ipvsadm -A -f 99 -s rr -p ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g 持久連接的實現: 每端口持久:PPC,單服務持久調度,sh算法實現的功能 每fwm持久:PFWMC,單FWM持久調度 每客戶端持久:PCC,單客戶端持久調度, director會將用戶的任何請求都識別為集群服務,並向RS調度,而且綁定到同一個RS上 1-65535 端口0:表示所有服務 ipvsadm -A -t 172.16.100.68:0 -s rr HA: SPOF:單點故障 lvs HA功能: director:在節點級別進行冗余;HA集群解決方案:keepalived,; real server:讓director 健康狀態檢測,並能夠完成自動上下線; 健康時:online 非健康時:offline 如何對real server做健康狀態檢測: (1) ip層:探測主機的存活狀態 ping;----單服務 並不一定 正常,如 web服務器,雖然主機好了,但是web就好嗎? (2) 傳輸層:探測端口的可用性;----端口好,不一定網頁就能訪問 (3) 應用層:請求關鍵的某資源;----直接請求某資源 狀態變化: ok --> failure --> failure --> failure rs: down soft state --> hard state failure --> ok rs: up backup(sorry_server): 示例腳本: #!/bin/bash # fwm=6 sorry_server=127.0.0.1 rs=(172.16.100.21 172.16.100.22) rw=(1 2) type=-g chkloop=3 rsstatus=(0 0) logfile=/var/log/ipvs_health_check.log addrs() { ipvsadm -a -f $fwm -r $1 $type -w $2 [ $? -eq 0 ] && return 0 || return 1 } delrs() { ipvsadm -d -f $fwm -r $1 [ $? -eq 0 ] && return 0 || return 1 } chkrs() { local i=1 while [ $i -le $chkloop ]; do if curl --connect-timeout 1 -s http://$1/.health.html | grep "OK" &> /dev/null; then return 0 fi let i++ sleep 1 done return 1 } initstatus() { for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then rsstatus[$host]=1 fi else if [ ${rsstatus[$host]} -eq 1 ]; then rsstatus[$host]=0 fi fi done } initstatus while :; do for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then addrs ${rs[$host]} ${rw[$host]} [ $? -eq 0 ] && rsstatus[$host]=1 fi else if [ ${rsstatus[$host]} -eq 1 ]; then delrs ${rs[$host]} ${rw[$host]} [ $? -eq 0 ] && rsstatus[$host]=0 fi fi done sleep 5 done 附:director和rs的示例腳本 DR類型director腳本示例: #!/bin/bash # vip=172.16.100.33 rip=(172.16.100.8 172.16.100.9) weight=(1 2) port=80 scheduler=rr ipvstype=-g case $1 in start) iptables -F -t filter ipvsadm -C ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up echo 1 > /proc/sys/net/ipv4/ip_forward ipvsadm -A -t $vip:$port -s $scheduler [ $? -eq 0 ] && echo "ipvs service $vip:$port added." || exit 2 for i in `seq 0 $[${#rip[@]}-1]`; do ipvsadm -a -t $vip:$port -r ${rip[$i]} $ipvstype -w ${weight[$i]} [ $? -eq 0 ] && echo "RS ${rip[$i]} added." done touch /var/lock/subsys/ipvs ;; stop) echo 0 > /proc/sys/net/ipv4/ip_forward ipvsadm -C ifconfig eth0:0 down rm -f /var/lock/subsys/ipvs echo "ipvs stopped." ;; status) if [ -f /var/lock/subsys/ipvs ]; then echo "ipvs is running." ipvsadm -L -n else echo "ipvs is stopped." fi ;; *) echo "Usage: `basename $0` {start|stop|status}" exit 3 ;; esac DR類型RS腳本示例: #!/bin/bash # vip=172.16.100.33 interface="lo:0" case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig $interface $vip broadcast $vip netmask 255.255.255.255 up route add -host $vip dev $interface ;; stop) echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig $interface down ;; status) if ifconfig lo:0 |grep $vip &> /dev/null; then echo "ipvs is running." else echo "ipvs is stopped." fi ;; *) echo "Usage: `basename $0` {start|stop|status}" exit 1 esac

Cluster了解+LB{ LVS(四種模式)+ipvs+lvs持久連接 }