盧至彤,李 翀,柯 勇,孫健英
(中國科學(xué)院 計(jì)算機(jī)網(wǎng)絡(luò)信息中心,北京 100190)
一種MongoDB應(yīng)用優(yōu)化策略①
盧至彤,李 翀,柯 勇,孫健英
(中國科學(xué)院 計(jì)算機(jī)網(wǎng)絡(luò)信息中心,北京 100190)
為了解決不斷增長的文件存儲需求,和高流量高并發(fā)的訪問量,增強(qiáng)系統(tǒng)的響應(yīng)性能,提出一種Web應(yīng)用優(yōu)化策略,通過MongoDB GridFS對網(wǎng)站文件存儲容量、可用性和可靠性進(jìn)行擴(kuò)展,并且通過Nginx和Keepalived,對后臺訪問進(jìn)行負(fù)載均衡和雙機(jī)熱備,優(yōu)化并發(fā)性能.實(shí)驗(yàn)表明,當(dāng)并發(fā)訪問數(shù)上升至80以上時,平均訪問響應(yīng)時間縮短9%.文件通過Nginx Gridfs進(jìn)行高并發(fā)上傳時非常穩(wěn)定,在較大文件下載時比直接通過本地文件系統(tǒng)EXT4下載速度更高.
MongoDB;GridFS;Nginx;Keepalived;concurrency
Web應(yīng)用通過文件服務(wù)器對圖片、視頻和文檔資源對文件進(jìn)行管理,包括:文件存儲、文件同步和文件訪問.對于大多數(shù)應(yīng)用而言,需要文件系統(tǒng)來存儲用戶上傳的文件.一般而言,用戶上傳的單個文件所占用的空間一般不大,但是上傳的文件數(shù)量是在不斷快速增長的.單機(jī)文件系統(tǒng)存儲容量可能會超過單機(jī)硬盤的擴(kuò)容范圍而且其查詢性能在存儲量級過大時查找和插入性能都可能會遇到瓶頸.我們可以采用MongoDB GridFS[1]分布式文件系統(tǒng)來達(dá)到我們動態(tài)增加存儲容量的目的.
除此以外,MongoDB GridFS分布式文件系統(tǒng)能夠自動進(jìn)行冗余備份,保證用戶的文件不會丟失;還有高可用性,也就是說當(dāng)某個文件服務(wù)器出現(xiàn)故障的時候,自動切換到備份提供服務(wù),使用戶感覺不到有什么異常.
隨著Web應(yīng)用訪問量的提高,我們可以通過Nginx反向代理服務(wù)器的負(fù)載均衡來提升Web應(yīng)用的響應(yīng)性能.對于負(fù)載均衡集群架構(gòu)系統(tǒng),各服務(wù)器間需要共享session信息,我們可以通過Memcache[2]這個高性能的分布式的內(nèi)存對象緩存系統(tǒng)來解決這個問題.
本文通過MongoDB GridFS分布式文件系統(tǒng)對網(wǎng)站文件存儲容量、可用性和讀取性能進(jìn)行擴(kuò)展.通過Nginx[3]代理服務(wù)器大量的并發(fā)訪問或數(shù)據(jù)流量分擔(dān)到多臺節(jié)點(diǎn)設(shè)備上分別處理,減少用戶等待響應(yīng)的時間,優(yōu)化并發(fā)性能.
系統(tǒng)設(shè)計(jì)架構(gòu)示意圖如圖1所示,系統(tǒng)通過Nginx代理服務(wù)器實(shí)現(xiàn)對于業(yè)務(wù)服務(wù)器和文件服務(wù)器集群的訪問,其中系統(tǒng)使用兩臺代理服務(wù)器采用雙機(jī)熱備技術(shù)確保系統(tǒng)的可靠性.通過設(shè)置負(fù)載均衡集群將訪問業(yè)務(wù)分?jǐn)偟絻膳_業(yè)務(wù)服務(wù)器上,降低了單個業(yè)務(wù)服務(wù)器的訪問壓力.主從代理服務(wù)器的負(fù)載均衡是使用Nginx作為反向代理服務(wù)器來實(shí)現(xiàn)的.
圖1 系統(tǒng)架構(gòu)圖
分布式文件系統(tǒng) MongoDB GridFS部署在MongoDB分布式數(shù)據(jù)庫上.數(shù)據(jù)庫分成三個分片[4]進(jìn)行橫向擴(kuò)展.每個分片由3臺Mongod Server副本集組成以保證可靠性.
1.1 負(fù)載均衡集群架構(gòu)
系統(tǒng)使用2臺Nginx代理服務(wù)器作為系統(tǒng)的出口,通過一個虛擬IP對外提供服務(wù),如下圖2所示.為保證系統(tǒng)的高可用性,采用雙機(jī)熱備模式.兩臺代理服務(wù)器同一時間只有一臺在提供服務(wù).當(dāng)提供服務(wù)的一臺出現(xiàn)故障的時候,另外一臺會馬上自動接管并且提供服務(wù),進(jìn)行無縫交接.雙機(jī)熱備是通過路由冗余協(xié)議在2臺代理服務(wù)器上分別安裝KeepAlive并進(jìn)行配置實(shí)現(xiàn)的.
1.2 MongoDB副本集
副本集架構(gòu)如下圖3所示,系統(tǒng)中一共包含4個副本集,每個副本集包含3個副本,分別是一個Primary,2個Secondary.3個副本在同步之后存儲的是同一份數(shù)據(jù).其中,主節(jié)點(diǎn)負(fù)責(zé)整個副本集的數(shù)據(jù)寫入,從節(jié)點(diǎn)定期從主節(jié)點(diǎn)通過Oplog同步數(shù)據(jù)備份,通過配置可從距離最近節(jié)點(diǎn)讀取數(shù)據(jù),實(shí)現(xiàn)讀寫分離.副本集之間通過心跳維持聯(lián)系,一但主節(jié)點(diǎn)掛掉失去聯(lián)系,從節(jié)點(diǎn)就會選舉一個新的主節(jié)點(diǎn),選舉過程對客戶端是透明的.副本集提供了數(shù)據(jù)的冗余備份,并因在多個服務(wù)器上可讀取存儲的數(shù)據(jù)副本,提高了數(shù)據(jù)的可用性和故障容忍性.
圖3 副本集架構(gòu)圖
1.3 MongoDB分片架構(gòu)
為提高存儲空間,分擔(dān)請求負(fù)載,采用MongoDB集群的分片配置[5],如下圖4所示.整個分片集群不同服務(wù)器分別承擔(dān)以下不同角色:
①M(fèi)ongos Server,路由服務(wù)器,數(shù)據(jù)庫集群請求的入口,負(fù)責(zé)把對應(yīng)的數(shù)據(jù)請求請求轉(zhuǎn)發(fā)到對應(yīng)的分片服務(wù)器上.管理操作、讀寫操作都通過mongos server來完成,以保證集群多個組件處于一致的狀態(tài).
②Config Server,配置服務(wù)器,存儲所有數(shù)據(jù)庫元信息的配置,即各個chunk與分片服務(wù)器的映射關(guān)系.如下圖所示,將配置服務(wù)器配置成一個副本集防止系統(tǒng)單點(diǎn)故障.
③Shard Server,分片服務(wù)器,存儲數(shù)據(jù)庫中具體的的數(shù)據(jù).其中,每一個分片服務(wù)器是一個副本集保證數(shù)據(jù)可用性.如下圖所示,集群有3個分片服務(wù)器,必要時還可進(jìn)行擴(kuò)展.
在分片服務(wù)器里,MongoDB會把數(shù)據(jù)根據(jù)片鍵分為chunks,如圖5所示.當(dāng)一個chunk的大小超過配置中的chunk size時,MongoDB的后臺進(jìn)程會把這個chunk切分成更小的chunk.除此之外,MongDB的后臺進(jìn)程Balancer負(fù)責(zé)chunk的遷移,從而均衡各個分片服務(wù)器的負(fù)載.這些過程對客戶端都是透明的.
圖4 MongoDB分片架構(gòu)圖
圖5 MongoDB chunk分布圖
1.4 GridFS
GridFS[6]是MongoDB之上的分布式文件系統(tǒng),通過MongoDB的復(fù)制,分片等機(jī)制來存儲文件數(shù)據(jù)和文件元數(shù)據(jù)并進(jìn)行管理與分析.GridFS將二進(jìn)制數(shù)據(jù)大文件分成很多塊,每一塊作為一個單獨(dú)的文檔存儲.
GridFS使用兩個文檔來存儲二進(jìn)制數(shù)據(jù)文件,一個用來存儲文件本身的塊,另外一個用來存儲分塊的信息和文件的元數(shù)據(jù),默認(rèn)對應(yīng)的集合分別為fs.chunks和fs.files,其結(jié)構(gòu)如圖6所示.
fs.files這個集合Collection存儲文件元數(shù)據(jù),一般比較小,不需要分片存儲.fs.chunks這個集合Collection存儲了文件數(shù)據(jù),比較大,根據(jù)files_id,n作為片鍵將不同chunk通過哈希分布到不同分片服務(wù)器上.
圖6 GridFS文件存儲
2.1 運(yùn)行環(huán)境
運(yùn)行環(huán)境集群中有7臺服務(wù)器,其環(huán)境如表2所示,其中每臺服務(wù)器的配置環(huán)境如表1所示.
表1 服務(wù)器配置信息
2.2 配置
2.2.1 MongoDB和GridFS配置
MongoDB的配置[7]示意圖如下圖所示.在如下的配置中,任何一臺機(jī)器因故障不能提供服務(wù),都能保證MongoDB繼續(xù)提供正常的服務(wù),數(shù)據(jù)不丟失,保證容災(zāi)性.并且在相應(yīng)的配置后,能增加和減少節(jié)點(diǎn),有良好的可擴(kuò)展性.
在四個服務(wù)器上開啟Mongod服務(wù),然后對Shard1、Shard2、Shard3和configReplSet副本集用mongo命令進(jìn)行連接,然后在Mongo Shell中配置副本集信息,如下所示.
表2 服務(wù)器集群環(huán)境
添加分片用命令mongo進(jìn)行連接mongos服務(wù)器端口,然后在MongoShell中配置分片信息,如下所示.
在新建數(shù)據(jù)庫test之后,對數(shù)據(jù)庫test開啟分片. GridFS默認(rèn)使用兩種集合 Collection:fs.files和fs.chunks來存儲數(shù)據(jù),對集合fs.chunks開啟分片和索引.在Mongo Shell中的配置如下所示:
2.2.2 Tomcat和Mysql安裝配置
Tomcat業(yè)務(wù)服務(wù)器集群結(jié)構(gòu)如圖7所示.
圖7 Tomcat服務(wù)器集群結(jié)構(gòu)
表3 Mongo服務(wù)器配置
在服務(wù)器 06、07,也就是 10.10.1.139和10.10.1.144上下載并安裝Tomcat 8.并將Java Web應(yīng)用打包成 war包,然后發(fā)布到 Tomcat服務(wù)器的webapps目錄下.并在服務(wù)器06上安裝和啟動Mysql. Web應(yīng)用使用其作為數(shù)據(jù)庫服務(wù)器.
2.2.3 Nginx、Memcached和Keepalived配置安裝
在服務(wù)器07上用git下載nginx-gridfs插件,并安裝和編譯,命令如下所示:
在nginx配置文件中配置負(fù)載均衡業(yè)務(wù)服務(wù)器與MongoDB Mongos IP地址與端口,如下所示.
Mencached是一個高性能的分布式的內(nèi)存對象緩存系統(tǒng),負(fù)責(zé)業(yè)務(wù)服務(wù)器間共享session對象信息,在服務(wù)器07上安裝和啟動.然后在服務(wù)器06和07的Tomcat里配置支持Mencached的session管理,即修改文件server.xml,添加Mencached服務(wù)器配置信息.
在服務(wù)器05和服務(wù)器06上,下載安裝Keepalived,并對Keepalived的配置文件keepalived.conf進(jìn)行配置,在其中設(shè)置服務(wù)器05是主服務(wù)器,而06是備服務(wù)器.然后,在這2臺服務(wù)器上啟用Keepalived服務(wù).為了使主服務(wù)器Keepalived正常運(yùn)行而Nginx出現(xiàn)故障時,關(guān)閉服務(wù),能夠順利切換,創(chuàng)建監(jiān)控腳本,并在Keepalived配置文件中實(shí)現(xiàn)監(jiān)控.
3.1 響應(yīng)性能測試
對部署在系統(tǒng)中Web應(yīng)用的響應(yīng)性能用Jmeter進(jìn)行測試,其中采用的Web測試應(yīng)用的后臺技術(shù)架構(gòu)是SpringMVC3.對部署在單個服務(wù)器上的同一Web應(yīng)用響應(yīng)性能對比.分別模擬30,50,80,100,120個用戶在1秒內(nèi)發(fā)出HTTP請求以測試其并發(fā)性能,測量值分別如下表3所示.其中,Samples表示一共完成了多少個線程,Average表示平均響應(yīng)時間,單位是毫秒, Median表示統(tǒng)計(jì)意義上面的響應(yīng)時間的中值,單位是毫秒,99%Line表示所有線程中99%的線程的響應(yīng)時間都小于或大于當(dāng)前數(shù)值,單位是毫秒,Min表示最小響應(yīng)時間,單位是毫秒,Max表示最大響應(yīng)時間,單位是毫秒.
可看到,隨著并發(fā)訪問數(shù)的提高,優(yōu)化后的系統(tǒng)的響應(yīng)時間越少,吞吐量越大.然而,并發(fā)訪問數(shù)提高,漸漸超過系統(tǒng)的承受能力,錯誤率也開始提高.在并發(fā)訪問為80及80以下時,單服務(wù)器響應(yīng)性能均比優(yōu)化后的系統(tǒng)表現(xiàn)要好,這可能是因?yàn)檫€沒達(dá)到單服務(wù)器并發(fā)性能極限,而且,通過Nginx請求轉(zhuǎn)發(fā)還需要相應(yīng)的時間消耗.在并發(fā)訪問為80左右時,平均響應(yīng)時間縮短9%,其趨勢如下圖8所示.這可能是因?yàn)?隨著并發(fā)訪問數(shù)的提高,單服務(wù)器響應(yīng)性能逐漸降低,而通過Nginx的分發(fā)和兩臺服務(wù)器分擔(dān)請求,單個服務(wù)器所需承擔(dān)的并發(fā)數(shù)下降,其服務(wù)器響應(yīng)性能也維持在較高的狀態(tài).而在并發(fā)訪問數(shù)達(dá)到100時,單服務(wù)器開始出錯,說明已經(jīng)達(dá)到它的并發(fā)極限.而優(yōu)化后的系統(tǒng)運(yùn)行良好.直到并發(fā)訪問數(shù)達(dá)到120,才達(dá)到優(yōu)化后的系統(tǒng)的并發(fā)極限.
表4 并發(fā)訪問數(shù)據(jù)對比
圖7 平均響應(yīng)時間增長趨勢圖
3.2 GridFS文件并發(fā)讀寫性能
3.2.1 GridFS文件并發(fā)寫性能
通過GridFS Java驅(qū)動,編寫Java測試應(yīng)用程序,在其中創(chuàng)建并發(fā)訪問線程進(jìn)行測試,模擬并發(fā)訪問十次的平均值,以減少誤差.然后與Linux EXT4文件系統(tǒng)在500K和20M大小的文件寫文件效率進(jìn)行對比,并記錄其響應(yīng)時間,如下圖所示.其中文件都是保存在同一個目錄下.可以看出,無論是在大文件還是小文件, GridFS文件上傳時間雖然比EXT4要慢.但是,隨著并發(fā)數(shù)的上升,文件上傳的最大時間是比較穩(wěn)定的.
上傳時間較慢原因有以下幾個:第一,在寫文件時,觀察GridFS數(shù)據(jù)庫分片狀態(tài)的變化,發(fā)現(xiàn)文件寫入總是在同一個節(jié)點(diǎn)上.這是因?yàn)榧蟜s.chunks的分片片鍵是(files_id,n),而其中files_id是自動生成的.在這種情況下,插入總是在一個分片上操作.第二,由于Balancer的Chunks均衡時要鎖定資源,速度較慢,來不及將新插入的Chunks遷移.第三,在集合fs.files和fs.chunks上建立了索引,對插入速度也有影響.第四,其他因素的影響可能導(dǎo)致結(jié)果有誤差,如CPU資源,緩存資源的占用等.
3.2.2 GridFS文件并發(fā)讀性能
通過MongoDB GridFS的JavaAPI測試文件的下載效率.GridFS下載測試是通過Nginx GridFS模塊在Nginx上下載,而對比的是通過TomcatWeb服務(wù)器在EXT4本地文件系統(tǒng)上下載,在這里搭建了NFS文件共享系統(tǒng)方便進(jìn)行對比.500K和500M空間大小的文件下載時間如下圖8所示,其中文件都是保存在同一個目錄下.
圖8 500K和20M文件并發(fā)上傳時間
GridFS的并發(fā)查詢優(yōu)勢在于通過Balancer的策略將數(shù)據(jù)塊chunks的查詢均勻的分布在各個分片上,訪問負(fù)載也隨著分散到各個分片上,從而提高并發(fā)性能.事實(shí)上,當(dāng)存儲的文件數(shù)據(jù)量少,由于路由查詢等消耗,GridFS的優(yōu)勢并不明顯.除此之外,相對于Linux EXT4文件系統(tǒng)的單個目錄下能存放的文件和文件夾數(shù)目有限而且過多的文件數(shù)目會導(dǎo)致文件搜索時間過長的問題而言,GridFS將文件名和路徑信息存放在fs.files里面則沒有這些問題.
文件下載速度與當(dāng)前網(wǎng)絡(luò)帶寬關(guān)系密切,而網(wǎng)絡(luò)帶寬是隨著時間動態(tài)變化的.測試雖然采取多次測量取平均值,仍然可能導(dǎo)致數(shù)據(jù)測量有一定偏差.
針對不斷提高的文件存儲需求以及高流量高并發(fā)的Web應(yīng)用訪問有延遲的問題,本文提出了一種Web優(yōu)化策略對網(wǎng)站響應(yīng)性能、文件存儲容量、可用性、可靠性和并發(fā)讀取性能等方面進(jìn)行提升.對這種優(yōu)化的部署架構(gòu)的響應(yīng)性能和文件下載速率做了實(shí)驗(yàn)和測試發(fā)現(xiàn),通過Nginx系統(tǒng)在高并發(fā)情況下有9%的性能提升.而且MongoDB Gridfs集群的文件上傳速率穩(wěn)定,下載速率在文件較大的情況下性能較好.
1 Chodorow K.MongoDB:The Definitive Guide.O’Reilly Media,Inc.2013.
2 Fitzpatrick B.Distributed caching with memcached.Linux Journal,2004,(124):72–76.
3 Chi X,Liu B,Niu Q,et al.Web load balance and cache optimization design based nginx under high-concurrency environment.2012 Third International Conference on Digital Manufacturing and Automation(ICDMA).IEEE.2012. 1029–1032.
4 Liu Y,Wang Y,Jin Y.Research on the improvement of MongoDB auto-sharding in cloud environment.2012 7th International Conference on Computer Science&Education (ICCSE).IEEE.2012.851–854.
5 Jiang W,Zhang L,Liao X,et al.A novel clustered MongoDB-based storage system for unstructured data with high availability.Computing,2014,96(6):455–478.
6 Gu Y,Wang X,Shen S,et al.Analysis of data storage mechanism in NoSQL database MongoDB.2015 IEEE International Conference on Consumer Electronics-Taiwan (ICCE-TW).IEEE.2015.70–71.
7劉一夢.基于MongoDB的云數(shù)據(jù)管理技術(shù)的研究與應(yīng)用[碩士學(xué)位論文].北京:北京交通大學(xué),2012.
Optimisation Strategy for WebApplications Based on MongoDB
LU Zhi-Tong,LI Zhong,KE Yong,SUN Jian-Ying
(Computer Network Information Center,ChineseAcademy of Sciences,Beijing 100190,China)
With the growing demand for massive file storage and high number of concurrent accesses to enhance performance of the system.In this paper,we propose an optimization strategy of web applications,which can expand the storage capacity,availability and reliability with MongoDB GridFS,and also can support load balancing and hot standby with Nginx and Keepalived,optimizing concurrent performance.We test the concurrent performances of the web application and the experimental results show that the average response time could be reduce by 9%when the number of concurrent accesses increases to more than 80.When files are uploaded concurrently through Nginx Gridfs,the performance is stable.The file-download speeds of larger files are faster than those through local file system EXT4.
MongoDB;GridFS;Nginx;Keepalived;concurrency
2016-09-05;收到修改稿時間:2016-10-17
10.15888/j.cnki.csa.005767