黃杰+周國祥+石雷
摘要:為了滿足網(wǎng)站對于信息發(fā)布后實時性的要求,針對于當前內(nèi)存保存數(shù)據(jù)庫備份的緩存模式,建立了以內(nèi)存作為緩存模型的第一保存點,數(shù)據(jù)庫作為數(shù)據(jù)備份方式,從而既滿足了信息的實時性,又保證了數(shù)據(jù)的安全性。通過在券媽媽網(wǎng)站的實際使用,驗證了該方法的實用性。
關鍵詞:內(nèi)存;緩存;數(shù)據(jù)庫;WEB網(wǎng)站;性能優(yōu)化
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2016)10-0040-04
Abstract: In order to meet the requirement of real-time information after release.To change the memory as the first save point,make the database as backup of of memory.Its not only meet the demand of security but also real-time.The method is verified by the actual use of the quanmama website.
Key words: memory; cache; database; WEB site; performance optimization
1 背景
緩存技術目前廣泛應用于各類型WEB網(wǎng)站中,根據(jù)網(wǎng)站的訪問量,每個網(wǎng)站都有自身一套的緩存方案,緩存實質(zhì)上是將存在于硬盤上的數(shù)據(jù),以KEY-VALUE模式存儲在內(nèi)存中,以增加訪問者獲取數(shù)據(jù)的速度。
國內(nèi)外的大型網(wǎng)站,都有一套自身的緩存方案,比如淘寶的tair系統(tǒng)[1],這些網(wǎng)站都擁有著足夠的服務器資源,而對于很多中小型網(wǎng)站受限于服務器資源,并不能使用這些方案來解決自身的網(wǎng)站緩存問題。而傳統(tǒng)的緩存方案多是將數(shù)據(jù)庫中數(shù)據(jù)保存到內(nèi)存中,設定失效時間,失效時間到期后重新從數(shù)據(jù)庫中獲取,再重新保存到內(nèi)存中[2],這種方案對于對數(shù)據(jù)時效性要求不高的網(wǎng)站可以使用,而對于數(shù)據(jù)時效性相對敏感的券媽媽網(wǎng)站這套基本方案并不合適。券媽媽網(wǎng)站主要的任務是發(fā)布各種優(yōu)惠信息,而優(yōu)惠信息對時效性要求較高,所以需要盡量的加快優(yōu)惠信息從產(chǎn)生到被網(wǎng)站曝光的速度。如果采用傳統(tǒng)的緩存失效,從數(shù)據(jù)庫中重新獲取這套方案,會大幅度減慢曝光速度,而如果減少緩存失效時間,使得緩存在內(nèi)存中更新頻率加快,使得網(wǎng)站硬件資源負擔加重[3],增加網(wǎng)站安全隱患。
在券媽媽實際運營中,網(wǎng)站建立了一套適用于券媽媽網(wǎng)站特點的緩存機制,將內(nèi)存作為數(shù)據(jù)的第一保存點,再定期的將數(shù)據(jù)備份到數(shù)據(jù)庫中,通過服務器的內(nèi)存作為第一時間保存,且同時與數(shù)據(jù)庫之間保持一致性[4]。以期同時滿足數(shù)據(jù)的安全性和時效性。
2 緩存技術方案優(yōu)化
2.1 網(wǎng)站簡介
券媽媽網(wǎng)站是以發(fā)布各大B2C優(yōu)惠信息為主的導購類網(wǎng)站,日均訪問約10萬PV(page view即頁面瀏覽量),3萬UV(user view即用戶瀏覽量),網(wǎng)站訪問者在時間上有高度的重疊性,在訪問的內(nèi)容上有高度的相似性,非常適合使用緩存機制。
灰色線UV表示userview,代表有多少用戶訪問。
黑色線PV表示pageview,代步這些用戶一共看了多少個頁面。
大致可以可以得出每個用戶大約看三個優(yōu)惠信息頁面,這使得我們在設計內(nèi)存中緩存的頁面數(shù)時,將每個分類對應緩存在內(nèi)存中的數(shù)據(jù)定為5頁,以盡量滿足用戶對于實時性的要求。
2.2 緩存模型
2.2.1 緩存基本框架
①:數(shù)據(jù)爬蟲獲取各大商家的優(yōu)惠信息,以時間屬性,不重復的保存至數(shù)據(jù)庫。
②:在數(shù)據(jù)庫中的數(shù)據(jù)進入待審核狀態(tài)。
③:被審核的數(shù)據(jù)分為通過和不通過兩類。
④:通過的數(shù)據(jù),首先直接保存到內(nèi)存的循環(huán)數(shù)組中。
⑤:不通過的數(shù)據(jù),將原始數(shù)據(jù)庫中對應的數(shù)據(jù),置為無效狀態(tài)。
⑥:保存到內(nèi)存中的數(shù)據(jù),定時同步到數(shù)據(jù)中。
⑦:當網(wǎng)站首次啟動時,會從數(shù)據(jù)庫中將對應的數(shù)據(jù)同步到內(nèi)存中來。
網(wǎng)站緩存采用的是以內(nèi)存為第一保存點,審核即發(fā)布的方式,加快信息曝光速度。首先網(wǎng)站在內(nèi)存中定義了一個長度為5000的常駐循環(huán)數(shù)組,作為優(yōu)惠信息的基本保存數(shù)據(jù)結(jié)構(5000條數(shù)據(jù)基本上可以保證三天內(nèi)的數(shù)據(jù)都能保存在數(shù)組里面),并且數(shù)組初始化時就為其初始化賦值,每個中都保存著優(yōu)惠信息數(shù)據(jù)結(jié)構的空字段信息,這樣省了在有新的優(yōu)惠信息插入時new的動作,節(jié)約了內(nèi)存分配的一些時耗(網(wǎng)站服務器端使用的是IIS服務,基于的.net平臺,使用了垃圾回收機制,這種機制會導致在分配和回收資源時對CPU和內(nèi)存的消耗)[5],這樣每次插入新的數(shù)據(jù)時,實質(zhì)上是執(zhí)行了更新操作。我們?yōu)檠h(huán)數(shù)組的頭和尾分表定義了整形變量HeadIndex,TailIndex來表示當前數(shù)組中第一位和最后一位的數(shù)據(jù)位置。
當每次有新數(shù)據(jù)需要插入到數(shù)組時會根據(jù)循環(huán)數(shù)組的頭指針(HeadIndex)和尾指針(TailIndex)的大小來執(zhí)行不同的操作:
①:當TailIndex>HeadIndex且TailIndex不等于4999的時候,此時表示數(shù)組TailIndex后的數(shù)組中數(shù)據(jù)均可更新,只需要將TailIndex加1,同時將TailIndex所指向的數(shù)據(jù)更新為插入的數(shù)據(jù)即可。
②:當TailIndex
③:當重新部署網(wǎng)站的時候,網(wǎng)站部署的同時,會將數(shù)據(jù)庫中按時間逆序的前5000條數(shù)據(jù)插入到循環(huán)數(shù)組中。再次插入新數(shù)據(jù)時,執(zhí)行步驟②。
分頁緩存控制:由于用戶瀏覽數(shù)據(jù)都是按頁來獲取數(shù)據(jù)的[6],當數(shù)據(jù)通過循環(huán)數(shù)組的結(jié)構保存在內(nèi)存中,就需要對數(shù)據(jù)進行按頁為單位進行組織,以方便用戶訪問。網(wǎng)站采用兩級Key-Value形式組織。
第一級:以分頁條件為Key值,分頁條件以優(yōu)惠信息分類為基本組合,以當前分頁條件中所含的數(shù)據(jù)對應的ID號為Value值,Value采用鏈表結(jié)構來保存數(shù)據(jù)(因為涉及到刪除操作)[7],鏈表的長度為20。每個分頁條件最多保留五頁數(shù)據(jù),即同分類條件在第一次緩存中最多對應5個Key,當用戶訪問第6頁時從數(shù)據(jù)庫中獲取,另建緩存(這點基于每個用戶在券媽媽大約看3個頁面,PV為3)[8]。當插入新數(shù)據(jù)時,首先會以當前數(shù)據(jù)的分類條件定位到key,再遍歷該Key所對應的Value鏈表,如果有當前數(shù)據(jù)所對應的ID則將該節(jié)點,插入到鏈表的第一位。如果沒有當前數(shù)據(jù)的ID則判斷是否鏈表已經(jīng)20個數(shù)據(jù)了,滿20則到該分類條件對應分頁的下一頁中執(zhí)行同樣的操作。其次會遍歷所有的key所對應的Value鏈表,對所有其中包含ID的,進行刪除操作,由于被替換的ID,都是最舊的數(shù)據(jù),肯定都保存在鏈表的最后一位,故只需查詢每個鏈表的最后一位,直接刪除即可。因為下一頁的數(shù)據(jù)永遠比上一頁的數(shù)據(jù)早出現(xiàn),所以刪除的節(jié)點一定是當前分頁條件的最后一頁的鏈表的最后一個數(shù)據(jù),不會出現(xiàn)第一頁19條數(shù)據(jù),第二頁20條數(shù)據(jù)的情況。
第二級:Value所對應的鏈表中保存的是當前分頁所對應的數(shù)據(jù)在數(shù)組中的下標ID,用戶訪問到當前分頁時,即首先獲取鏈表中的ID值,再根據(jù)ID值直接從數(shù)組中將對應的數(shù)據(jù)取出來,生成HTML值,返回給用戶。同時數(shù)組設計成循環(huán)模式[9],在插入數(shù)據(jù)時,選擇到最早插入的數(shù)據(jù),直接對其進行更新成最新的數(shù)據(jù)。第二級的數(shù)據(jù),在網(wǎng)站部署/重啟時,會與數(shù)據(jù)庫直接通信,從數(shù)據(jù)庫中選擇前5000條數(shù)據(jù),并根據(jù)數(shù)據(jù)的分類對第一級數(shù)據(jù)進行重構。
2.2.2 數(shù)據(jù)的更新刪除
由于優(yōu)惠信息有過期和錯誤的屬性,所以對于已保存到數(shù)組中對應的數(shù)據(jù)有需要更新,刪除的操作。
更新:即找到對應的數(shù)據(jù)在數(shù)組中保存的位置,直接更新,同時將數(shù)據(jù)對應于數(shù)據(jù)庫中的也同時更新,保持數(shù)據(jù)一致性。
刪除:由于數(shù)組的特殊數(shù)據(jù)結(jié)構,其刪除操作會比較耗費時間[10],所以對于要刪除的數(shù)據(jù)在數(shù)組中只是將其狀態(tài)設置為刪除狀態(tài),并不真正操作數(shù)組刪除行為。同時對于第一級緩存中的value進行更改[11]。刪除操作大致為如下:
①:遍歷當前數(shù)據(jù)對應分類第一頁的鏈表,如果存在,則直接刪除當前鏈表中對應的數(shù)據(jù),并且同時判斷第二頁鏈表是否有數(shù)據(jù),如果有將第二頁鏈表的數(shù)據(jù)的第一個摘下,插入到第一頁鏈表的尾端。再判斷第三頁鏈表是否有數(shù)據(jù),如果有將第一個數(shù)據(jù)摘下保存到第二頁鏈表的的尾端。
②:如果遍歷第一頁數(shù)據(jù)不存在要刪除的數(shù)據(jù),則遍歷第二頁鏈表,如果存在執(zhí)行步驟①。
③:如果前兩頁鏈表都不存在要刪除的數(shù)據(jù),則遍歷第三頁鏈表,同時直接刪除對應的數(shù)據(jù)。
3 實驗分析
由于網(wǎng)站的部署基本都選擇在夜晚訪問者最少的時間,所以我們分析的是網(wǎng)站穩(wěn)定后,新數(shù)據(jù)審核通過后,網(wǎng)站的整體性能,以及網(wǎng)頁數(shù)據(jù)的更新速度[12]。實驗條件將網(wǎng)站部署在券媽媽的圖片服務器上。由于實驗對比的是不同的地方,所以對于網(wǎng)絡傳輸速度等不予考慮。
①不使用任何緩存:每次數(shù)據(jù)插入都直接插入到數(shù)據(jù)庫之中,每個用戶訪問都是直接通過執(zhí)行SQL來返回給用戶對應的數(shù)據(jù),所以其時耗主要在數(shù)據(jù)庫執(zhí)行上,當用戶訪問過多時,數(shù)據(jù)庫會負載過重。
②使用簡單的緩存:每次用戶第一次訪問時,從數(shù)據(jù)庫中將對應的數(shù)據(jù)保存到緩存中并設定失效時間,其余任何用戶訪問相同的頁面時,返回的都是直接從內(nèi)存中對應的數(shù)據(jù),當數(shù)據(jù)失效后,用戶再次訪問時會重新從數(shù)據(jù)庫中獲取。這種方式最為簡單,但是會出現(xiàn)用戶看不到最新的數(shù)據(jù)情況。用戶會看到已經(jīng)失效的優(yōu)惠信息。如果將失效時間設置過短,又會使得緩存更新過快,加重數(shù)據(jù)庫負擔。
③網(wǎng)站自用緩存機制:當新數(shù)據(jù)插入到內(nèi)存中,首先會將數(shù)據(jù)插入的數(shù)組中時間復雜度為o(1),然后會遍歷第一級緩存,對應的key,執(zhí)行插入操作,時間復雜度為o(1)。對此外的key進行刪除操作時間復雜度為o(1)。遍歷整個第一級緩存時間復雜度為o(n)。數(shù)據(jù)從數(shù)組中獲取,并返回的時間復雜度為o(20)。如果出現(xiàn)刪除操作,其時間復雜度為o(60)。這樣其對數(shù)據(jù)庫壓力遠遠小于方式①和方式②,頁面的更新速度也遠超過方式②,整體其時間復雜度為線性。對于網(wǎng)站的整體性能也基本不會產(chǎn)生影響。
3.1 實驗數(shù)據(jù)采集
我們按上述三種方式分別部署了不同性質(zhì)的網(wǎng)站,并且不斷地向網(wǎng)站插入新的數(shù)據(jù),并對實驗數(shù)據(jù)進行了采集。每次訪問間隔10分鐘。
CPU:訪問時,服務器端的CPU使用率。
內(nèi)存:訪問時,服務器端的內(nèi)存使用率。
響應時間:從訪問開始到網(wǎng)頁渲染(即數(shù)據(jù)已經(jīng)返回)[13]。
數(shù)據(jù)更新:數(shù)據(jù)插入后,多久頁面被更新。
可以看出采用方式③無論是從對CPU,內(nèi)存的消耗,還是響應時間以及數(shù)據(jù)的及時性,都得到了一定的提升,在有限的條件下,使得網(wǎng)站性能得以明顯的提升。
4 結(jié)束語
網(wǎng)站的打開速度和用戶的離開速度有著直接的關聯(lián),而在有限的硬件資源下,就必須通過合理的優(yōu)化方案來實現(xiàn)高速的響應效果,通過常態(tài)化的一些優(yōu)化手段和網(wǎng)站自用的緩存方案,券媽媽網(wǎng)站基本上保證了日均10萬PV的正常訪問,這也基本上證明了,這套方案的實用性。網(wǎng)站的優(yōu)化方案,必須得切合好網(wǎng)站的實際使用情況,網(wǎng)站的真實訪問流量情況來決定,用戶對于不同的網(wǎng)站,其期待的效果不一致。券媽媽網(wǎng)站主要提供的優(yōu)惠信息和商品導購,這類信息用戶更加期望有效,準確,及時。故而針對于此網(wǎng)站采用內(nèi)存為第一保存點,以便直接將審核好的信息快速反饋給用戶。
參考文獻:
[1] 子柳. 淘寶技術這十年[M]. 北京: 電子工業(yè)出版社, 2013.
[2] Patrick Killelea. 優(yōu)化 Web 性能[M]. 周新紅, 譯.北京: 中國電力出版社, 2000: 78-80.
[3] 吳安. 基于 MVC 設計模式的系統(tǒng)框架研究與設計[D]. 江蘇: 江蘇大學, 2009: 56-59.
[4] 張熙. Web 應用性能優(yōu)化模型及測試框架的研究[D]. 南京: 南京航空航天大學, 2008: 38-40.
[5] Jeffrey Richter.CLR via C#[M]. 3版.北京: 清華大學出版社, 2010.
[6] Steve Holzner. Design Patterns For Dummies[M]. John Wiley & Son, 2006, 230-235.
[7] 王珊, 肖艷芹, 劉大為, 等. 內(nèi)存數(shù)據(jù)庫關鍵技術研究[J]. 計算機應用, 2007, 10.
[8] 程舒通, 徐從富. 網(wǎng)站結(jié)構優(yōu)化技術研究進展[J]. 計算機應用研究, 2009, 26(6): 2013-2015.
[9] 奚冬芹, 林文龍, 竺炯林. 基于隱馬爾可夫模型的電子商務網(wǎng)站結(jié)構優(yōu)化[J]. 計算機應用研究, 2009, 26(3): 946-948.
[10] 嚴蔚敏. 數(shù)據(jù)結(jié)構(c語言版)[M]. 北京: 清華大學出版社, 2007.
[11] 譚駿珊, 吳昌盛. 基于 B/S 模式應用系統(tǒng)性能優(yōu)化的研究[J]. 計算機應用, 2003: 2-3.
[12] Garcia-Molina H, Salem K. Main memory database systems: an overview[J]. Knowledge and Data Engineering,IEEE Transactions, 1992, 4(6): 509-516.
[13] 李守振, 張南平. Web應用分層與開發(fā)框架設計研究[J]. 計算機工程, 2006, 32(22): 274-276.