LVS解決高併發,大數據量

 

http://www.360doc.com/content/14/0726/00/11962419_397102114.shtmlhtml

 

LVS的全稱Linux vitual system,是由目前阿里巴巴的著名工程師章文嵩博士開發的一款開源軟件。LVS工做在一臺server上提供Directory(負載均衡器)的功能,自己並不提供服務,只是把特定的請求轉發給對應的realserver(真正提供服務的主機),從而實現集羣環境中的負載均衡。linux

LVS的核心組件ipvs工做在kernel中,是真正的用於實現根據定義的集羣轉發規則把客戶端的請求轉發到特定的realserver。而另外一個組件ipvsadm是工做在用戶空間的一個讓用戶定義ipvs規則的工具。故咱們只要在server上裝了ipvsadm軟件包就能夠定義ipvs規則,而在linux kernel的2.6版本以後kernel是直接支持ipvs的。web

注:因爲ipvs是接受netfilter五個鉤子函數的中的local_in函數控制的。故ipvs不能和netfilter的一些控制規則同時使用。算法

 

好了,進入正題,如下是今天所分享的主要內容:apache

LVS三種模型LVS-NAT2,LVS-DR,LVS-TUN的工做原理及環境搭建。vim

實驗環境:redhat enterprise 5.4+ipvsadm+httpd(用於提供web服務)後端

這些爲LVS環境搭建中的一些專業名詞:瀏覽器

RIP:realserver的ip地址緩存

DIP:director的ip地址服務器

CIP:用戶客戶端的ip地址

VIP:虛擬ip地址(這個ip地址是用戶請求的提供服務的ip地址)

 

一,LVS-NAT

工做原理圖:

153355337.jpg

工做原理:

圖3.1:VS/NAT的體系結構

客戶經過Virtual IP Address(虛擬服務的IP地址)訪問網絡服務時,請求報文到達調度器,調度器根據鏈接調度算法從一組真實服務器中選出一臺服務器,將報文的目標地址Virtual IP Address改寫成選定服務器的地址,報文的目標端口改寫成選定服務器的相應端口,最後將修改後的報文發送給選出的服務器。同時,調度器在鏈接Hash表中記錄這個鏈接,當這個鏈接的下一個報文到達時,從鏈接Hash表中能夠獲得原選定服務器的地址和端口,進行一樣的改寫操做,並將報文傳給原選定的服務器。當來自真實服務器的響應報文通過調度器時,調度器將報文的源地址和源端口改成Virtual IP Address和相應的端口,再把報文發給用戶。咱們在鏈接上引入一個狀態機,不一樣的報文會使得鏈接處於不一樣的狀態,不一樣的狀態有不一樣的超時值。在TCP鏈接中,根據標準的TCP有限狀態機進行狀態遷移;在UDP中,咱們只設置一個UDP狀態。不一樣狀態的超時值是能夠設置的,在缺省狀況下,SYN狀態的超時爲1分鐘,ESTABLISHED狀態的超時爲15分鐘,FIN狀態的超時爲1分鐘;UDP狀態的超時爲5分鐘。當鏈接終止或超時,調度器將這個鏈接從鏈接Hash表中***。

這樣,客戶所看到的只是在Virtual IP Address上提供的服務,而服務器集羣的結構對用戶是透明的。對改寫後的報文,應用增量調整Checksum的算法調整TCP Checksum的值,避免了掃描整個報文來計算Checksum的開銷。

特色:

1,全部的realserver和director要在同一個網段內

2,VIP生產環境爲公網ip,而DIP用於和rs通訊

3,director同時處理請求和應答數據包

4,realserver的網關要指向DIP

5,能夠實現端口映射

6,realserver能夠是任意操做系統

7,director極可能成爲系統性能瓶頸

實驗拓撲:

153504890.jpg

Director這臺server爲雙網卡eth0用於客戶端的請求,而eth1用於和realserver通訊。

客戶端經過請求172.16.30.1提供web服務。請根據拓撲配置好網絡。

1,rs1上的配置:

配置好rs1上的yum源,能夠指向咱們的系統安裝光盤。

rs1是做爲一臺realserver使用,故須要安裝httpd提供web服務:

# yum -y install httpd

添加測試頁:

# cd /var/www/html

# vim index.html

添加以下內容:

jia's server1

啓動httpd服務:

# service httpd start

測試rs1上的web服務:

153709323.jpg

路由的配置:

# route add default gw 192.168.1.1

2,rs2上的配置:

配置好rs2上的yum源,能夠指向咱們的系統安裝光盤。

rs2是做爲一臺realserver使用,故須要安裝httpd提供web服務:

# yum -y install httpd

添加測試頁:

# cd /var/www/html

# vim index.html

添加以下內容:

jia's server2

啓動httpd服務:

# service httpd start

測試rs2上的web服務:

153802824.jpg

路由的配置:

# route add default gw 192.168.1.1

3,director上的配置:

安裝ipvsadm軟件包:(ipvsadm在安裝光盤的Cluster目錄中,請確認yum源指向)

# yum -y install ipvsadm

打開本機的路由轉發功能:

先查看路由轉發是否打開:

# cat /proc/sys/net/ipv4/ip_forward

若是顯示值爲1,則打開,能夠跳過此步驟。若是值爲0,則開啓此功能。

開啓路由轉發:

# sysctl -w net.ipv4.ip_forward=1 (臨時生效)

能夠修改配置文件使其永久生效:

# vim /etc/sysctl.conf

修改net.ipv4.ip_forward = 0此行爲net.ipv4.ip_forward = 1便可

使用ipvsadm對ipvs進行配置,因爲ipvs的十種算法中,wlc算法是最優算法,也是默認算法,故咱們僅以此爲例進行配置:

# ipvsadm -A -t 172.16.30.1:80 -s wlc

# ipvsadm -a -t 172.16.30.1:80 -r 192.168.1.10 –m –w 3

# ipvsadm -a -t 172.16.30.1:80 -r 192.168.1.11 –m –w 1

查看配置是否生效:

# ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port      Forward Weight ActiveConn InActConn

TCP 172.16.30.1:80 wlc

-> 192.168.1.11:80       Masq  1   0     0    

-> 192.168.1.10:80       Masq  3   0     0

ok,咱們的LSV-NAT配置好了,下面咱們來對其進行測試:

咱們能夠多刷新頁面獲取效果或換個瀏覽器。

153922666.jpg

爲了更好的演示效果,咱們能夠用另外一臺server對httpd服務進行壓力測試:

# ab -c 100 -n 10000 http://172.16.30.1/index.html (ab工具是apache自帶壓力測試工具)

在director上查看請求響應結果:

# ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port      Forward Weight ActiveConn InActConn

TCP 172.16.30.1:80 wlc

-> 192.168.1.11:80       Masq  1   16     4194  

-> 192.168.1.10:80       Masq  3   62     3997

因爲咱們使用的是wlc算法,且權重比爲3:1,故活動鏈接數的比幾乎也爲3:1。使用不一樣的調度算法,顯示的結果是不同的。

 

二,LVS-DR(生產環境下應用最爲普遍)

工做原理圖:

154239621.jpg

工做原理:基於直接路由來實現。當一個client發送一個WEB請求到VIP,LVS服務器根據VIP選擇對應的real-server的Pool,根據算法,在Pool中選擇一臺 Real-server,LVS在hash表中記錄該次鏈接,而後將client的請求包發給選擇的Real-server,最後選擇的Real- server把應答包直接傳給client;當client繼續發包過來時,LVS根據更才記錄的hash表的信息,將屬於這次鏈接的請求直接發到剛纔選 擇的Real-server上;當鏈接停止或者超時,hash表中的記錄將被***。DR模式在轉發client的包時,只修改了包目的MAC地址爲選定的Real-server的mac地址,因此若是LVS和Real-server在不一樣的廣播域內,那麼Real-server就沒辦法接收到轉發的包。這個方式是三種調度中性能最好的,也是咱們生產環境中使用最多的。

特色:

1,集羣節點和director必須在一個物理網絡內

2,RIP可使用公網地址或私有地址

3,director僅處理入站請求

4,集羣節點網關不指向director,故出站不通過director

5,不支持端口映射

6,大多數操做系統能夠做爲realserver,要支持隔離arp廣播

7,director服務器的壓力比較小

實驗拓撲:

200225774.jpg

director只須要一個網卡eth0便可,把VIP配置在eth0的別名eth0:0上便可。咱們經過VIP地址192.168.1.1給用戶提供web服務。

注:生產環境下VIP應該是一個公網ip地址

1,rs1上的配置:

配置好rs1上的yum源,能夠指向咱們的系統安裝光盤。

rs1是做爲一臺realserver使用,故須要安裝httpd提供web服務:

# yum -y install httpd

添加測試頁:

# cd /var/www/html

# vim index.html

添加以下內容:

jia's server1

啓動httpd服務:

# service httpd start

因爲DR模型在內網中基於mac地址進行轉發請求數據包,而且咱們的director和realserver都配有一個VIP地址,故咱們要限制realserver的arp通告和arp響應級別,以保證咱們數據包能到達director指定要發送的realserver。而咱們的linux系統提供了這樣的功能,經過修改kernel的兩個參數來控制arp的級別。

兩個重要的arp參數:

 

arp_announce = 2

表示忽略使用要發送的ip數據包的源地址來設置ARP請求的源地址,而由系統來選擇最好的接口來發送。首要是選擇全部的網絡接口的子網中包含該目標IP地址的本地地址。 若是沒有合適的地址被發現,將選擇當前的要發送數據包的網絡接口或其餘的有可能接受到該ARP迴應的網絡接口來進行發送。而Linux默認狀況下,是使用要發送的ip數據包中的源ip地址做爲arp請求的源地址,而默認這種方式對lvs是否是適用的,具體問題爲:rs會把本身的vip做爲arp請求的源地址,而路由器收到這個arp請求就會更新本身的arp緩存,修改vip對應的mac爲rs的,這樣就會形成ip欺騙了,正在lvs上的VIP被搶奪,因此就會有問題。

 

 

arp_ignore = 1

表示若是此server接受的arp請求的目的地址,不是該arp請求包進入的接口配置的ip地址,那麼不迴應此arp請求。(若是lvs的vip配置在rs的eth0:1邏輯網口,這個arp_ignore將失去做用。由於任何設備發送對vip的arp廣播,數據包也會從rs的eth0進入,那麼rs上的vip因爲在eth0:1上,因此就會對此arp請求就行response,致使網絡混亂)

 

配置以下:

# 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別名,而且定義lo:0的廣播域爲本網卡,使VIP不能向網絡內發送廣播,以防止網絡出現混亂:

# ifconfig lo:0 192.168.1.1 broadcast 192.168.1.1 netmask 255.255.255.255

測試rs1上的web服務:

154411224.jpg

rs2上的配置:

和rs1上的配置徹底同樣,這裏再也不闡述。

測試rs2的web服務:

154453248.jpg

director上的配置:

配置好yum源,安裝ipvsadm

# yum install ipvsadm

# ifconfig eth0:0 192.168.1.1 broadcast 192.168.1.1 netmask 255.255.255.255

# route add -host 192.168.1.1 dev eth0:0

# echo 1 > /proc/sys/net/ipv4/ip_forward

以上的配置咱們上邊已經闡述配置理由

配置ipvs集羣服務:

# ipvsadm -A -t 192.168.1.1:80 -s wlc

# ipvsadm -a -t 192.168.1.1:80 -r 192.168.1.10 –g –w 10

# ipvsadm -a -t 192.168.1.1:80 -r 192.168.1.11 –g –w 5

查看:

# 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.1.1:80 wlc

-> 192.168.1.11:80       Route  5   0     0    

-> 192.168.1.10:80       Route  10   0     0  

好了,LVS-DR模型搭建好了,咱們來測試一下:

因爲咱們制定的調度算法和權重不一樣,故咱們多刷新幾回就有效果了。

154547411.jpg

咱們一樣能夠用apache的壓力測試工具ab來測試httpd,從而獲得調度算法的效果,方法和LVS-NAT的同樣,不在闡述。

 

三,LVS-TUN

因爲LVS-TUN的模型用的不普遍,若是網絡很差會有不少瓶頸,通常沒有企業使用,故這裏不在探討它的配置過程,只說一下它的工做原理。

工做原理圖:

154657586.jpg

IP隧道(IP tunneling)是將一個IP報文封裝在另外一個IP報文的技術,這可使得目標爲一個IP地址的數據報文能被封裝和轉發到另外一個IP地址。IP隧道技術亦稱爲IP封裝技術(IP encapsulation)。IP隧道主要用於移動主機和虛擬私有網絡(Virtual Private Network),在其中隧道都是靜態創建的,隧道一端有一個IP地址,另外一端也有惟一的IP地址。

 

工做原理:這種方法經過ip隧道技術實現虛擬服務器。

1> client 發送request包到LVS服務器的VIP上。

2> VIP按照算法選擇後端的一個Real-server,並將記錄一條消息到hash表中,而後將client的request包封裝到一個新的IP包裏,新IP包的目的IP是Real-server的IP,而後轉發給Real-server。

3> Real-server收到包後,解封裝,取出client的request包,發現他的目的地址是VIP,而Real-server發如今本身的 lo:0口上有這個IP地址,因而處理client的請求,而後real-server將直接relpy這個request包直接發給client。

4> 該client的後面的request包,LVS直接按照hash表中的記錄直接轉發給Real-server,當傳輸完畢或者鏈接超時,那麼將***hash表中的記錄。

因爲經過IP Tunneling 封裝後,封裝後的IP包的目的地址爲Real-server的IP地址,那麼只要Real-server的地址能路由可達,Real-server在什麼 網絡裏均可以,這樣能夠減小對於公網IP地址的消耗,可是由於要處理IP Tunneling封裝和解封裝的開銷,那麼效率不如DR模式。

特色:

1,realserver和director能夠不在一個物理網絡中

2,director要有到realserver的路由

3,director僅處理入站請求

4,realserver的網關不能指向DIP

5,不支持端口映射

6,支持ip隧道功能的操做系統才能做爲realserver

因爲須要Real-server支持IP Tunneling,因此設置與DR模式不太同樣,LVS不須要設置tunl設備,LVS自己能夠進行封裝

rs的配置:

只須要配置VIP在tunl設備上便可:(vip:172.16.1.1)

# ifconfig tunl0 172.16.1.1 netmask 255.255.255.255

# ifconfig tunl0

tunl0 Link encap:IPIP Tunnel HWaddr

inet addr:172.16.1.1 Mask:255.255.255.255

UP RUNNING NOARP MTU:1480 Metric:1

RX packets:0 errors:0 dropped:0 overruns:0 frame:0

TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

 

四,lvs簡單調優

1,調整ipvs connection hash表的大小

IPVS connection hash table size,取值範圍:[12,20]。該表用於記錄每一個進來的鏈接及路由去向的信息。鏈接的Hash表要容納幾百萬個併發鏈接,任何一個報文到達都須要查找鏈接Hash表,Hash表是系統使用最頻繁的部分。Hash表的查找複雜度爲O(n/m),其中n爲Hash表中對象的個數,m爲Hash表的桶個數。當對象在Hash表中均勻分佈和Hash表的桶個數與對象個數同樣多時,Hash表的查找複雜度能夠接近O(1)。

鏈接跟蹤表中,每行稱爲一個hash bucket(hash桶),桶的個數是一個固定的值CONFIG_IP_VS_TAB_BITS,默認爲12(2的12次方,4096)。這個值能夠調整,該值的大小應該在 8 到 20 之間,詳細的調整方法見後面。每一行都是一個鏈表結構,包含N列(即N條鏈接記錄),這個N是無限的,N的數量決定了決定了查找的速度。

LVS的調優建議將hash table的值設置爲不低於併發鏈接數。例如,併發鏈接數爲200,Persistent時間爲200S,那麼hash桶的個數應設置爲儘量接近200x200=40000,2的15次方爲32768就能夠了。當ip_vs_conn_tab_bits=20 時,哈希表的的大小(條目)爲 pow(2,20),即 1048576,對於64位系統,IPVS佔用大概16M內存,能夠經過demsg看到:IPVS: Connection hash table configured (size=1048576, memory=16384Kbytes)。對於如今的服務器來講,這樣的內存佔用不是問題。因此直接設置爲20便可。

關於最大「鏈接數限制」:這裏的hash桶的個數,並非LVS最大鏈接數限制。LVS使用哈希鏈表解決「哈希衝突」,當鏈接數大於這個值時,必然會出現哈稀衝突,會(稍微)下降性能,可是並不對在功能上對LVS形成影響。

 

調整 ip_vs_conn_tab_bits的方法:

新版的linux kernel中的IPVS代碼,容許調整 ip_vs_conn_bits 的值。而老kernel中的的IPVS代碼則須要經過從新編譯內核來進行調整。

在linux kernel發行版裏,IPVS一般是以模塊的形式編譯的。

確認可否調整使用命令 modinfo -p ip_vs(查看 ip_vs 模塊的參數),看有沒有 conn_tab_bits 參數可用。假如能夠用,那麼說時能夠調整,調整方法是加載時經過設置 conn_tab_bits參數:

在/etc/modprobe.d/目錄下添加文件ip_vs.conf,內容爲:

options ip_vs conn_tab_bits=20

查看

ipvsadm -l

若是顯示IP Virtual Server version 1.2.1 (size=4096),則前面加的參數沒有生效

modprobe -r ip_vs

modprobe ip_vs

從新查看

IP Virtual Server version 1.2.1 (size=1048576)

假如沒有 conn_tab_bits 參數可用,則須要從新調整編譯選項,從新編譯。

Centos6.2,內核版本2.6.32-220.13.1.el6.x86_64,仍然不支持這個參數,只能自定義編譯了。

另外,假如IPVS支持調整 ip_vs_conn_tab_bits,而又將IPVS集成進了內核,那麼只能經過重啓,向內核傳遞參數來調整了。在引導程序的 kernel 相關的配置行上,添加:ip_vs.conn_tab_bits=20 ,而後,重啓。

或者從新編譯內核。

 

2,linux系統參數優化

關閉網卡LRO和GRO

如今大多數網卡都具備LRO/GRO功能,即 網卡收包時將同一流的小包合併成大包 (tcpdump抓包能夠看到>MTU 1500bytes的數據包)交給 內核協議棧;LVS內核模塊在處理>MTU的數據包時,會丟棄;

所以,若是咱們用LVS來傳輸大文件,很容易出現丟包,傳輸速度慢;

解決方法,關閉LRO/GRO功能,命令:

ethtool -k eth0 查看LRO/GRO當前是否打開

ethtool -K eth0 lro off 關閉GRO

ethtool -K eth0 gro off 關閉GRO

禁用ARP,增大backlog併發數

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

net.core.netdev_max_backlog = 500000  (在每一個網絡接口接收數據包的速率比內核處理這些包的速率快時,容許送到隊列的數據包的最大數目)

 

3,lvs自身配置

儘可能避免sh算法

一些業務爲了支持會話保持,選擇SH調度算法,以實現 同一源ip的請求調度到同一臺RS上;但 SH算法本省沒有實現一致性hash,一旦一臺RS down,,當前全部鏈接都會斷掉;若是配置了inhibit_on_failure,那就更悲劇了,調度到該RS上的流量會一直損失;

實際線上使用時,如需 會話保持,建議配置 persistence_timeout參數,保證一段時間同一源ip的請求到同一RS上。

 

4,手動綁定linux系統網卡中斷
lvs的併發過大,對網卡的利用很頻繁,而對網卡的調優,也能增長lvs的效率。當前大多數系統網卡都是支持硬件多隊列的,爲了充分發揮多核的性能,須要手動將網卡中斷(流量)分配到全部CPU核上去處理。默認狀況下,網卡的全部的中斷都是發送到一個默認的cpu上去處理的,而cpu中斷須要等待時間,這樣對於使用網卡頻繁的服務,網卡性能就會成爲瓶頸。
1,查看網卡中斷:
# cat /proc/interrupts

2,綁定網卡中斷到cpu

例如將中斷52-59分別綁定到CPU0-7上:

[plain] view plaincopy

echo "1" > /proc/irq/52/smp_affinity  

echo "2" > /proc/irq/53/smp_affinity  

echo "4" > /proc/irq/54/smp_affinity  

echo "8" > /proc/irq/55/smp_affinity  

echo "10" > /proc/irq/56/smp_affinity  

echo "20" > /proc/irq/57/smp_affinity  

echo "40" > /proc/irq/58/smp_affinity  

echo "80" > /proc/irq/59/smp_affinity  

/proc/irq/${IRQ_NUM}/smp_affinity爲中斷號爲IRQ_NUM的中斷綁定的CPU核的狀況。以十六進制表示,每一位表明一個CPU核。

        1(00000001)表明CPU0

        2(00000010)表明CPU1

        3(00000011)表明CPU0和CPU1

3,關閉系統自動中斷平衡:
# service irqbalance stop

4,若是網卡硬件不支持多隊列,那就採用google提供的軟多隊列RPS;配置方法同硬中斷綁定,例:# echo 01 > /sys/class/net/eth0/queues/rx-0/rps_cpus# echo  02 > /sys/class/net/eth0/queues/rx-1/rps_cpus

相關文章
相關標籤/搜索