梁 劍
(太原工業(yè)學院 計算機工程系,山西 太原 030008)
隨著互聯(lián)網(wǎng)應(yīng)用的發(fā)展,由多臺服務(wù)器分擔客戶的HTTP請求已經(jīng)廣泛部署到現(xiàn)實中.但是我們很難做出一個完美方案能解決合理分配負載.一般來說,服務(wù)器的資源包括CPU、內(nèi)存、硬盤IO等,如何充分利用這些資源是個難點。首先,很難根據(jù)一個URL來判斷是消耗了哪種資源,比如說圖片、HTML文檔這樣的靜態(tài)內(nèi)容主要消耗硬盤IO資源.如果是動態(tài)內(nèi)容,可能主要消耗CPU或內(nèi)存.第二,如何對后端資源進行價值度量,各種資源的值簡單相加并不合理.第三,合理利用所有資源未必是最優(yōu)選,比如當訪問的是熱數(shù)據(jù)時,結(jié)果會從緩存中取出而節(jié)約時間,任務(wù)分配不合理,可能會出現(xiàn)更多的鎖等待時間.
Nginx是由俄羅斯人Igor Sysoev開發(fā)的一款高性能Web服務(wù)器,同時還支持反向代理和負載均衡.由于使用了epoll這樣的多路復(fù)用IO技術(shù),Nginx所消耗的資源比傳統(tǒng)的Apache服務(wù)器要小,因此能支持更高的并發(fā)連接數(shù),根據(jù)NETCRAFT調(diào)查,在2018年1月占有25.39%的份額,并且還在快速增長中[5].
Nginx的反向代理是在ngx_http_upstream_module模塊中實現(xiàn)的[4],配置文件如下所示:
upstream backserver {
server backend.server.com weight=5;
server 127.0.0.1:1234 weight=10;}
upstream模塊可以通過proxy_pass被引用,配置如下所示:
server {
listen 8080;
proxy_pass backserver;}
1.2.1 輪詢算法
輪詢(round-robin)是Nginx的默認負載均衡算法,根據(jù)請求到來的順序,依次將任務(wù)分配給后端服務(wù)器,此算法的優(yōu)點是實現(xiàn)簡單,但是分配任務(wù)上沒有任何優(yōu)化,無法充分利用后端服務(wù)器資源.
1.2.2 會話保持算法
又稱IP_HASH方式,采用輪詢或共他負載均衡算法會造成同一用戶的請求分配到不同的服務(wù)器上,這種情況下必須使用session共享技術(shù),不同的服務(wù)器訪問來自同一源的session,可使用redis等技術(shù)來實現(xiàn).在Nginx中可以使用ip_hash指令配置此算法.此方法的好處是不需要解決不同服務(wù)器間的共享session問題,但其缺點是缺乏對任務(wù)分配的優(yōu)化.
1.2.3 加權(quán)輪詢負載均衡算法
加權(quán)輪詢負載均衡(Weighted Load Balancing)是在輪詢的基礎(chǔ)上根據(jù)服務(wù)器的負載能力來調(diào)整任務(wù)分配,前面提到的兩種算法中對待后端服務(wù)器是一視同仁,而現(xiàn)實中后端服務(wù)器的能力是有差別的.在Nginx輪詢方式的配置后面加上weight命令來指定服務(wù)器的權(quán)重.此算法的優(yōu)點是考慮了后端服務(wù)器能力的差異,其缺點是這種任務(wù)分配方式是靜態(tài)的,無法根據(jù)實際負載動態(tài)調(diào)整.
1.2.4 最少連接數(shù)負載均衡算法
最少連接數(shù)負載均衡(Least connected load balancing)就是根據(jù)前端任務(wù)分配器與后端服務(wù)器的連接數(shù)做為分配的依據(jù),連接數(shù)少的負荷小,連接數(shù)多的負荷大.新到的任務(wù)會分配到連接數(shù)少的服務(wù)器上.其優(yōu)點是考慮了服務(wù)器的動態(tài)負荷狀況,但其缺點是依賴連接數(shù)判斷負荷是不夠準確的,比如說連接數(shù)多并不能表明負荷重,也許是因為等待鎖資源,或者是在等待其他服務(wù)器(如數(shù)據(jù)庫服務(wù)器)完成任務(wù).
國內(nèi)外負載均衡算法的研究都比較多,總體上分為靜態(tài)和動態(tài)兩種類型.靜態(tài)類型就是不考慮后端服務(wù)器的工作狀況,根據(jù)預(yù)先設(shè)定的方式分配任務(wù),如Nginx中自帶的輪詢、加權(quán)輪詢以及會話保護方式.動態(tài)類型是根據(jù)后端服務(wù)器的負載狀況分配任務(wù),這其中又有兩種方式,一是根據(jù)連接數(shù)推測服務(wù)器的運行狀況;二是根據(jù)后端服務(wù)器將自身的負荷狀況反饋給任務(wù)分配器,以此信息做為任務(wù)分配依據(jù).
在文獻中提出了一種動態(tài)自適應(yīng)權(quán)重輪詢隨機負載均衡算法,將后端服務(wù)器的CPU、內(nèi)存、磁盤IO、網(wǎng)絡(luò)使用經(jīng)過加權(quán)計算得到資源使用率,將其反饋給任務(wù)分配服務(wù)器.但也應(yīng)該看到,其相比于加權(quán)最少連接數(shù)算法只有10%左右的性能提升,付出的代價是大大提高了系統(tǒng)復(fù)雜性.在文獻中提出了一種具有實時反饋能力的負載均衡算法,選擇了與文獻中近似的方法,通過計算后端服務(wù)器中CPU、內(nèi)存、IO的負荷情況反饋回前端負載均衡器.在文獻中提出了負載均衡算法,并且結(jié)合memcache,將CPU、網(wǎng)絡(luò)等資源使用情況反饋給前端負載均衡器.
綜上文獻看出現(xiàn)有的研究主要集中在后端服務(wù)器向前端反饋資源占用狀況,這種方式能一定程度準確反應(yīng)實際情況.但其問題有三,一是增加了復(fù)雜性;二是占用了資源,性能提升并不明顯.三是負載反饋具有滯后性,當短連接數(shù)較多時,無法反映出實際負載情況.
相比于依賴于后端服務(wù)器反饋負載情況,在負載均衡器上也能采集到負載情況的相關(guān)信息,如連接數(shù)、時延等.熱數(shù)據(jù)是指一段時間內(nèi)頻繁訪問的數(shù)據(jù),對于Web訪問來說,可以簡單地認為,相同的URL訪問出現(xiàn)熱數(shù)據(jù)的幾率要高得多.
設(shè)W(Ni)是為第i個后服務(wù)器的權(quán)重,W(Ni)權(quán)重主要考慮三個因素連接數(shù)、時延和URL的哈希.URL的哈希權(quán)值代表與熱數(shù)據(jù)的接近程度,按URL的哈希分配更能接近熱數(shù)據(jù).設(shè)URL經(jīng)過哈希運算后結(jié)果會落到[0,H)的區(qū)間上,則H(Ni)是URL相對于第i個服務(wù)器的權(quán)值,則有如下公式:
設(shè)C(Ni)為第i個的服務(wù)器的連接數(shù),D(Ni)為第i個服務(wù)器的平均延時值,則連接數(shù)與時延的聯(lián)合加權(quán)值W(Li)為:
設(shè)Ccnt為預(yù)先設(shè)定的常量,W(Ni)的值為:
圖1 實驗示意圖
那么第i個服務(wù)器分配到負載的概率Pi為:
實驗開發(fā)環(huán)境是使用五臺計算機,操作系統(tǒng)為CentOS6.9,一臺安裝Nginx作為負載均衡器,四臺作為后端服務(wù)器,安裝php_fpm服務(wù)軟件.壓力測試軟件使用Apache AB實驗圖如圖1所示.
實驗測試分別測試輪詢算法(RR),最少連接數(shù)算法(LC),基于熱數(shù)據(jù)的最少連接數(shù)算法(HLC),實驗做了5次取平均值.在表1中列出了三種算法的平均響應(yīng)時間,可以看到,使用LC算法要比傳統(tǒng)的輪詢算法響應(yīng)時間要少,而使用基于HLC算法,響應(yīng)時間更好.
表2測試了連接成功數(shù),可以看到相比于傳統(tǒng)的RR算法,LC算法的連接成功次數(shù)有了一定的提高,而使用HLC算法在連接成功數(shù)上與LC算法相當.
表1 平均響應(yīng)時延 ms
表2 連接成功數(shù)
相比于傳統(tǒng)的輪詢算法,最少連接數(shù)能夠提高負載均衡的性能,使用熱數(shù)據(jù)的最少連接數(shù)算法比較依賴于是否能讀到熱的數(shù)據(jù),所以不同的環(huán)境下可能性能表現(xiàn)會有差距.