羅貴章
(1.廣西大學計算機與電子信息學院,廣西 南寧 530004;2.百色職業(yè)學院,廣西 百色 533000;3.百色市機電工程學校,廣西 百色 533000)
Sakai[1]是由美國印第安納大學、密西根大學、斯坦福大學和麻省理工學院發(fā)起的一項開源課程與教學管理系統(tǒng)開發(fā)計劃[2]。Sakai 的核心是交互,包括學生與學生交互、學生與教師交互以及學生與學習資源交互?;⒍罚?]等使用Think Aloud 測試結合訪談法和觀察法,對Sakai 平臺的可用性進行深入的測試和研究,發(fā)現(xiàn)Sakai 平臺存在可用性問題,大量用戶并發(fā)訪問時候的響應速度慢。Sakai 是典型的Web應用系統(tǒng)。吳銳[4]基于Nginx 融合頁面壓縮構建了高性能的靜態(tài)頁面Web 系統(tǒng)。王亞楠[5]等針對高并發(fā)的Web 系統(tǒng),通過前端資源壓縮以及延遲加載,以及后端數(shù)據(jù)分頁和緩存技術,實現(xiàn)了高并發(fā)的Web系統(tǒng)。謝杰濤[6]等針對Web 緩存壓力,提出了一種基于定期更新和請求驅動更新的本地數(shù)據(jù)緩存機制,應用程序能夠根據(jù)待存儲數(shù)據(jù)的特點選擇合適的緩存方式。針對關系數(shù)據(jù)庫在非結構化數(shù)據(jù)存儲上的不足,MongoDB 等NoSQL 數(shù)據(jù)庫被應用于高性能Web 系統(tǒng)中[7]。針對Web 服務器的阻塞通信方式的不足,劉偉[8]等通過異步I/O 的方式構建高性能Web 服務系統(tǒng)。
本文在前人Web 系統(tǒng)相關工作基礎上,針對高負載Sakai 系統(tǒng)的特定情況,提出基于Linux 集群的優(yōu)化方案,通過HAProxy 實現(xiàn)負載均衡和熱備,并實現(xiàn)了主從/讀寫分離的MySQL 架構。通過實驗驗證,該系統(tǒng)具有良好的負載均衡、響應能力以及數(shù)據(jù)庫讀性能。
圖1 顯示了本文提出的針對Sakai 在線協(xié)作學習系統(tǒng)特性的、具有高可用性的Linux 集群的架構。主要配置包括:前端基于HAProxy[9]和Keepalived[10]的負載均衡器、NFS 集群、Apache 集群、Session 共享結點(Memcached[11])、MySQL 數(shù)據(jù)主從備份、MySQL 從服務器負載均衡層。
圖1 高可用的Linux 集群架構
在線協(xié)作學習系統(tǒng)主要應用部署于Web 服務器上。如果僅設置單個Web 服務器作為應用服務器,顯然無法滿足海量訪問請求的沖擊。于是本文提出了搭建Web 服務集群的方案,多個結點同時提供服務。
簡單地增加Web 服務器是不可行的。服務器增加后,出現(xiàn)了訪問請求的分發(fā)問題,即負載均衡問題[12]。如果負載均衡做得不好,會出現(xiàn)某些結點一直處于重載狀態(tài),甚至導致宕機。而另外一些結點在同一時刻可能處于空閑狀態(tài),造成資源的分配嚴重不合理[13]。因此,本文提出了基于HAProxy 的負載均衡集群。
圖2 HAProxy 負載均衡
圖1 中的Load Balancer 即為系統(tǒng)中的Web 服務器負載均衡層。如圖2 所示,顯示了HAProxy 的配置架構。HAProxy 作為前端直接面向外部網(wǎng)絡,提供請求代理分發(fā)服務。而應用服務器則是作為后端,專注于業(yè)務系統(tǒng),與前端耦合度為0。下面通過HAProxy的配置文件對負載均衡架構進行分析。本系統(tǒng)架構包括3 臺Web 服務器,其內(nèi)部IP 地址分別為172.18.16.2,172.18.16.3 和172.18.16.4。其中部署了2 個Web 應用:sakai_portal 和sakai_resource。HAProxy 工作的層次配置在HTTP 層。通過負載均衡機制,3 臺應用服務器可以根據(jù)權重獲得指定份額的訪問請求,達到高并發(fā)和高可用性的目的。
在圖1 中,HAProxy 結點使用了熱備機制,保證負載均衡結點的高可用性。采用的是Keepalived 作為備份監(jiān)控工具。雙機熱備的模式有2 種:Active-Standby 模式和Active-Active 模式。Active-Standby 模式下,只有一個可用的虛擬IP(對外IP)。一個結點對外提供服務,稱為MASTER 結點,該結點持有虛擬IP。而另一個結點只作為備份結點,不對外提供服務,稱為BACKUP 結點。當MASTER 結點不可用時,BACKUP 結點接管虛擬IP,進而接管MASTER 結點服務,如圖3 所示。
圖3 主-備模式熱備方案
主-備模式下,MASTER 結點一直處于工作狀態(tài),而BACKUP 結點永遠處于備用狀態(tài),這無疑給系統(tǒng)造成了資源較大浪費。雙主模式(Active-Active)下,2個服務器都處于工作狀態(tài)。如圖4 所示,此時需要分配2 個虛擬IP 地址,Node#1 配置為192.168.1.1 的虛擬IP 為MASTER 結點,192.168.1.2 為BACKUP結點;而Node#2 則與Node#1 完全反過來。這樣2 個結點互相認為對方是自己的后備結點,自己是主結點,從而實現(xiàn)了兩者的互備關系,形成了雙主模式。
圖4 雙主模式熱備方案
主-備模式的切換算法如圖5 所示。
圖5 主-備模式的切換算法
由圖5 算法ACTIVE-STANBY-FAILOVER 可知,主備模式的雙機熱備機制,在失效切換時,只需要將虛擬IP 漂浮到后備結點,并由后備結點接管所有已失效的主結點的連接,然后廣播消息即可完成。雙主模式的切換算法與主備模式的切換算法基本一致,只不過切換完成之后,仍然可用的結點擁有2 個虛擬IP地址,既充當Master 又扮演Backup 的角色。所有的連接都由該結點接管。
當Web 應用的業(yè)務規(guī)模和流量增大時,單臺服務器組成的網(wǎng)站架構是無法滿足發(fā)展需求的[14-15]。如圖1 所示的架構中,通過配置多臺Web 服務器,構建應用服務器集群,讓多臺服務器分攤高壓狀態(tài)下的請求量,從而提高系統(tǒng)吞吐能力、并發(fā)能力,進而增強了系統(tǒng)的高可用性。但是跨服務器的應用會產(chǎn)生Session 共享的問題,解決Session 共享問題變得非常重要。Session 共享的解決方案通常由以下幾種:基于Cookie、基于數(shù)據(jù)庫、基于內(nèi)存共享系統(tǒng)。內(nèi)存共享系統(tǒng)內(nèi)存中的HashMap 具有數(shù)據(jù)淘汰機制,完全符合Session 的過期機制。由于Sakai 的Session 數(shù)據(jù)量較大,綜合數(shù)據(jù)量和I/O 壓力,本文采取了基于Memcached 的Session 共享機制。
隨著業(yè)務量增加,數(shù)據(jù)庫讀寫壓力隨之增加,存儲設備I/O 負載提高[16]。提高數(shù)據(jù)庫的讀寫性能通常的做法是:1)增加數(shù)據(jù)庫緩存;2)采用一主多從式結構,將讀和寫分離;3)業(yè)務數(shù)據(jù)分庫處理。如圖6所示,本文針對在線協(xié)作學習系統(tǒng)具有大量“站點”和內(nèi)容資源的特性,提出數(shù)據(jù)庫高可用的架構。主結點的MySQL 實例只負責整個數(shù)據(jù)庫系統(tǒng)的寫操作。從結點可以有多個,根據(jù)系統(tǒng)需求可以靈活擴展從結點數(shù)量,而不會對原有系統(tǒng)造成任何影響。從結點只負責數(shù)據(jù)讀服務。顯然,對于大多數(shù)Web 應用,絕大多數(shù)請求都是對資源讀取的請求,要求寫數(shù)據(jù)庫的請求只是少數(shù)。因此,單個寫結點、多個讀結點正符合這種規(guī)律。多個從結點將極大地提高數(shù)據(jù)庫的并發(fā)讀能力。
圖6 主-從架構讀寫分離MySQL 集群
多個從結點同時提供讀服務,就會產(chǎn)生負載均衡問題。因此,對于從結點多于2 個時,需要加入負載均衡機制,保證Slave 集群高效、穩(wěn)定運行。
由于實驗條件的限制,本文所設置的實驗環(huán)境的服務器配置相對較低,服務器數(shù)據(jù)為4 臺,通過虛擬化實現(xiàn)多臺虛擬服務器。其中,3 個Web 服務器共用1 臺實體服務器,Memcached 和NFS 共用1 臺實體服務器,MysQL 集群共用1 臺實體服務器,而HAProxy共用1 臺實體服務器。Web 服務器的性能測試采用的是壓力測試工具Apache Jmeter[17]。
當服務器的配置相當時,通過HAProxy 負載均衡層處理之后的請求,理論上應平均地根據(jù)服務器的配置和負載狀況,分發(fā)到各個服務器上。如圖7 所示,顯示了服務器連接的分發(fā)結果。顯然,由于Sakai 平臺請求基本上都是短連接請求,因此可以近似地認為每個服務器接收到的連接處理的平均時間相等。從實驗結果可以看出,實驗用的3 臺Web 服務器在經(jīng)過負載均衡層后,所分配得到的連接數(shù)量相差不大。因此,從連接分配這個角度說明原型系統(tǒng)應用了高可用Linux 集群之后的負載均衡有了一定效果。
圖7 服務器連接分發(fā)平衡性
圖8 顯示的是各服務器在測試過程中CPU 空閑率的對比。顯然,3 個服務器的CPU 空閑率很接近,這是由于3 臺服務器的硬件配置是相同的,并且負載均衡層分配到的連接請求數(shù)量均衡,因此得到的結果如圖所示。
圖8 服務器CPU 資源的空閑率對比
如圖9 所示,在大量讀操作情況下,HAProxy 的負載均衡機制實現(xiàn)多個服務器并行對外提供讀服務。系統(tǒng)的讀取響應時間較小,并且隨著請求壓力的增加,響應時間沒有呈現(xiàn)暴漲的狀況。而無負載均衡的情況則隨著請求量增加,出現(xiàn)了響應時間急劇增加的狀況;尤其是達到16 000 次左右請求時候,服務器對請求的增加極其敏感。請求量達到30 000 次之后,服務器響應出現(xiàn)了大量的超時現(xiàn)象,而達到100 000次之后,基本上停止響應。
圖9 大量多讀操作下的響應時間對比
如圖10 所示,針對大量讀操作應用場景進行測試。通過實驗結果發(fā)現(xiàn),寫請求很顯然比讀操作耗費系統(tǒng)資源。在無負載均衡層的情況下,系統(tǒng)響應時間較早地進入了快速增加的階段,請求量達到1 000 次左右,就急劇增加,到2 000 次時,增速又一次提升。此時的服務器對新增請求非常敏感了,少量的請求量增加就會導致響應實現(xiàn)的大幅增加,請求量達到6 000 次時就出現(xiàn)大量的連接超時。HAProxy 的架構在本測試中,在寫操作達到3 000 次之前響應時間都較為穩(wěn)定,沒有出現(xiàn)較大的增加。但達到3 000 次后就出現(xiàn)了響應時間增加的現(xiàn)象,此時的服務器總的計算能力接近滿載荷。此后服務器雖然仍然有能力處理增加的請求量,但是由于服務器的I/O 能力已經(jīng)達到了瓶頸,雖然有負載均衡器的作用,仍然無法避免響應時間陡增。負載均衡器的作用,還是使得在響應時間雖然增加的情況下,仍然比無負載機制的情況要小很多。
圖10 大量寫操作下的響應時間對比
前文給出了針對原型系統(tǒng)的高可用數(shù)據(jù)庫的架構,即主從、讀寫分離的MySQL 集群,并為負責讀操作的Slave 結點集群加入負載均衡層,以實現(xiàn)高效的讀取操作。
由于Sakai 這類在線協(xié)議學習系統(tǒng)與大多數(shù)常規(guī)的Web 應用系統(tǒng)類似,都是以大量的讀請求居多,寫操作請求相對較少,因此,針對該特性提出重點加強讀操作的并發(fā)能力的要求。本文的原型系統(tǒng)讀操作的預期要比非讀寫分離的架構有較大性能提升,而讀操作預期性能則與非讀寫分離架構相當,甚至可能要差于后者(由于Slave 結點需要同步,故引發(fā)Master結點I/O 任務加重)。
圖11 數(shù)據(jù)庫讀操作性能對比
如圖11 所示,對比了MySQL 數(shù)據(jù)庫集群非讀寫分離結構(ds)和主從讀寫分離結構(ds(LB))的讀性能。讀寫分離的結構應對數(shù)據(jù)庫連接量的增加,其讀取操作的延遲并沒有巨大的增加,而維持在20 ms 左右。非讀寫分離結構隨著數(shù)據(jù)庫連接增加,延遲明顯增加。并且主從分離結構的查詢延遲明顯低于前者,這是由于Slave 結點并發(fā)的響應讀操作。本實驗環(huán)境下的Slave 結點數(shù)量為3,并且是虛擬機環(huán)境而非實體服務器,而非讀寫分離的服務器是單個實體服務器。在這種配置下,讀寫分離的結構就已經(jīng)達到接近非讀寫分離結構的3 倍性能,生產(chǎn)環(huán)境下其性能將更加優(yōu)秀。
從圖11 的實驗結果還可以看出,如預期的那樣,數(shù)據(jù)量的增加,對查詢的性能的影響并不大。由于關系數(shù)據(jù)庫使用了各種優(yōu)秀的索引技術和緩存技術,在服務器內(nèi)存可以承受的范圍內(nèi),增加數(shù)據(jù)庫記錄的數(shù)量,會使得索引數(shù)據(jù)增加。但對于查詢的性能并不會受到很大影響。因此,實驗結果中,不管是主從讀寫分離結構還是非分離結構,數(shù)據(jù)量增加的查詢延遲增加不大。
如圖12 所示,在數(shù)據(jù)庫寫操作的性能對比中,可以看出主從讀寫分離架構的寫操作性能并不比單點的架構優(yōu)秀。從本架構和相關分析可以知道,主從架構的主結點只負責用戶的寫請求,如果僅此而已其性能理論上會比單點架構要優(yōu)越。但是主從架構的一個重要操作就是主結點與從結點的數(shù)據(jù)同步操作。如果系統(tǒng)要求是強一致性,那么一個寫操作到達時,必須按照一致性要求,保證從結點是最新的數(shù)據(jù),同步操作就會耗去一定的時間。因此,從實驗的結果來看,主從結構的寫性能,稍差于單點結構。其中的另一個因素與本實驗環(huán)境配置有關,因為主從結構的實驗室在虛擬機環(huán)境下實現(xiàn),而單點結構則是實體機。
圖12 數(shù)據(jù)庫寫操作性能對比
從本節(jié)的實驗結果可以得出,主從讀寫分離的結構極其適合于讀密集型的Web 應用或其他類似應用,但是對于寫操作要求較高的(寫密集型)應用,則應適當?shù)卣{(diào)整結構。
本文針對開源在線協(xié)同學習系統(tǒng)Sakai 在高負載應用場景下,產(chǎn)生服務質(zhì)量不穩(wěn)定、可靠性低的問題,提出了基于Linux、HAProxy、Keepalived 以 及Memcached 的性能優(yōu)化方案。該方案在外圍接口采用HAProxy 進行第一級別的負載均衡。Memcached失效Web 服務器的Session 共享機制。在MySQL 數(shù)據(jù)庫性能提升上,采取“一主多從”架構,并且進行讀寫分離,在MySQL 讀服務器上融合了HAProxy 負載均衡,最終構成了適合高負載Sakai 系統(tǒng)的架構。實驗表明,本方案在Web 服務器負載均衡、響應能力以及數(shù)據(jù)庫讀性能上表現(xiàn)良好,但在數(shù)據(jù)庫寫性能上仍有待提高,這將是筆者未來工作的方向。
[1]Sakai.Sakai Project Homepage[EB/OL].http://www.sakaiproject.org/,2014-09-05.
[2]朱珂,劉清堂.Sakai 網(wǎng)絡教學平臺應用的影響因素探究[J].中國遠程教育,2013(15):71-74.
[3]虎二梅,郭玉清,馬海夫.開源教學平臺的可用性研究——以Sakai 為例[J].數(shù)學的實踐與認識,2013,43(2):138-144.
[4]吳銳.高并發(fā)Web 系統(tǒng)的設計與應用[J].電腦知識與技術,2013,13(9):3049-3052.
[5]王亞楠,吳華瑞,黃鋒.高并發(fā)Web 應用系統(tǒng)的性能優(yōu)化分析與研究[J].計算機工程與設計,2014,35(8):2976-2981.
[6]謝杰濤,吳敏,吳娟,等.Web 系統(tǒng)高性能本地數(shù)據(jù)緩存實現(xiàn)機制[J].計算機應用研究,2014,31(7):2074-2077.
[7]張文盛,鄭漢華.基于MongoDB 構建高性能網(wǎng)站技術研究[J].吉林師范大學學報(自然科學版),2013,34(1):123-127.
[8]劉偉,楊慧勇,喬建,等.使用異步I/O 構建高性能Web服務器[J].科技創(chuàng)新與生產(chǎn)力,2013(1):83-85,88.
[9]HAProxy.HAProxy Homepage[EB/OL].http://www.haproxy.org/,2014-06-23.
[10]Keepalived.Keepalived Homepage[EB/OL].http://www.keepalived.org/,2014-06-23.
[11]Brad Fitzpatrick.Distributed caching with memcached[J/OL].http://www.linuxjournal.com/issue/124,Linux Journal,2004(124),2004-08-01.
[12]Wei W,Dong S,Zhang L,et al.Animproved ganglia-like clusters monitoring system[M]// Grid and Cooperative Computing.Springer Berlin Heidelberg,2004:89-96.
[13]Liang Z,Sun Y,Zhang L,et al.Reverse auction-based grid resources allocation[M]// Agent Computing and Multi-Agent Systems.SpringerBerlin Heidelberg,2006:150-161.
[14]盧旭,程良倫.ASP 和ASP.NET 共享Session 狀態(tài)研究[J].計算機應用與軟件,2009,26(6):54-56.
[15]張穎楠,顧乃杰,彭建章,等.一種內(nèi)核級多進程負載均衡會話保持方法[J].計算機工程,2014,40(3):76-81.
[16]劉毅,王峰,周子健.主從模式研究所群組集成知識平臺設計與實現(xiàn)[J].現(xiàn)代圖書情報技術,2012,28(7/8):6-12.
[17]Apache.Apache Jmeter[EB/OL].http://jmeter.apache.org/,2014-06-23.