摘 要:在高并發和重負載情形下,對網站高效能的追求,是大型網站設計和優化的首要出發點。本文從靜態內容分離和應用拆分、存儲拆分、緩存機制和負載均衡四個方面簡要分析了高并發和重負載網站的技術架構,最后對系統架構設計的原則進行了簡單的探討。
關鍵詞:網站架構;應用拆分;存儲拆分;緩存體系;負載均衡
1 靜態內容分離和應用拆分
網站中效率最高、消耗最小的是純靜態化的HTML頁面。實現動態的數據和邏輯與靜態的表現相分離是高負載應用普遍采取的方法[2]。對于交互應用較少的頁面可以簡單的以靜態頁面呈現,而對于內容量大且頻繁更新的站點,則通常借助CMS系統批量的生成和維護靜態頁。HTML靜態化也是某些緩存策略的基礎,對于系統中頻繁使用數據庫查詢但是內容更新很小的應用,通常會使用靜態頁作為緩存的一部分,從而避免大量的數據庫訪問請求。
對于小型的web系統,由于負載較低,通常可將所有的應用邏輯在單一系統中實現。所有邏輯均在一個進程或一個應用中運行。但隨著系統用戶的增加和系統功能的擴展,系統復雜度將大大上升、系統維護和擴展的難度不斷增加,同時系統的可用性和伸縮性也會受到影響。因此有必要對大型的互聯網應用進行拆分,即,將原來的系統根據一定的標準(如業務相關性)拆分為不同子系統,分別負責不同的功能,從而可以大大的提升系統的水平伸縮性,可以有針對性的對重負載的子系統進行水平擴展而不會影響到其它的子系統,避免了單一系統存在的由于局部應用在重負載下崩潰而引起整個系統崩潰的現象發生。
2 存儲拆分
靜態內容分離后可以大大提升網站的負載能力,但仍無法突破海量數據集中存儲和訪問引起I/O效率瓶頸。因此在存儲的層面對系統進行拆分就至關重要。
2.1 數據庫拆分
大型網站通常由數據庫驅動,那么在面對大量訪問的時候,數據庫的瓶頸會很快出現。因此通常需要使用數據庫集群或者庫表散列對數據庫進行拆分。在數據庫集群方面,大多數數據庫廠商都有自己的解決方案。大型網站的數據庫集群架構通常參考選用數據庫廠商的解決方案實施,因此在成本、擴張性等方面也會受到所采用數據庫類型的限制。因此我們需要從應用程序的角度來考慮改善系統架構,庫表散列是常用并且最有效的解決方案。一方面可以按照功能進行垂直擴展,即將不同功能模塊的數據存儲在不同的數據庫中。這樣將一個較大的數據庫切分成多個小數據庫,從而實現數據庫的擴展。系統中各功能模塊后合度越低,則越容易使顯示數據庫的垂直切分。另一方面可以從數據的水平將表中的數據記錄且分到不同的數據庫中。為了能夠比較容易地判斷各行數據切分到了哪個數據庫中,切分總是需要按照某種特定的規則來進行的,如按照某個數字字段的范圍,某個時間類型字段的范圍,或者某個字段的hash值。
在大型網站中通常會綜合運用這兩種庫表散列方案,即按功能模塊將數據庫進行分離,不同的模塊對應不同的數據庫或者表,再按照一定的策略對某個頁面或者功能進行更小的數據庫散列,這樣就能夠低成本的提升系統的性能并且有很好的擴展性。
2.2 非結構化數據拆分
在一個大型的互聯網應用當中,除了可以用數據庫處理的結構化數據之外,還存在大量的非結構化數據,例如配置文件、視頻和圖片等。這些信息一般不適合保存到RDBMS中,或使用RDBMS管理會引起讀取性能的嚴重下降。因此這些非結構化的數據也需要和其它信息分開存儲,而一般的互聯網應用系統都會選擇把這些信息保存到分布式文件系統中[3],這樣的架構可以降低提供頁面訪問請求的服務器系統壓力,并且可以保證系統不會因為圖片問題而崩潰,保證更低的系統消耗和更高的執行效率。
分布式文件系統是實現非結構化數據存儲的主要技術,典型的分布式文件系統是GFS(Google File System)。其他開源組織開發的分布式文件系統,其基本思想和GFS一致。
3 緩存處理
采用緩存處理機制是大型網站應對訪問量持續增長,提升頁面響應速度的常用策略。重負載環境中常綜合采用下述幾種緩存機制:
客戶端緩存(client Page Cache):根據HTTP協議特性,修改Header參數(Cache-Control、Expires、Pragma、Last-Modified、Etag),讓瀏覽器來緩存頁面(一些優秀開發框架會對此做透明的封裝,例如:Beetle)。通過盡量使用GET請求、壓縮頁面、使用Cookie代替Session以及使用AJAX實現異步數據更新等,減少客戶端和服務器的數據流量[4],還可以采取瀏覽器插件技術突破瀏覽器功能限制,將原本在服務器端運算,盡量遷到瀏覽器端。
前端頁面緩存(Front Page Cache):訪客向網站發出訪問請求,由前端頁面緩存器負擔原服務器的處理進程做出響應,獲取原服務器的相應網頁內容,將其儲存在自身的內存中,與此同時,傳送給訪客這一緩存的內容;如有另一訪客也請求訪問之前的相同內容,前端頁面緩存器毋須再次獲取原服務器上的相應內容,而直接從自身的內存中獲取,將這一內容傳送給訪客。反之,前端頁面緩存器也可緩存訪客的GET和POST請求。在這種緩存架構中,訪客實際面對的是前端頁面緩存器,與網站之間的通訊完全由前端頁面緩存器反向代理,而非原服務器直接響應訪客,這將大大加快訪客上網流暢度,有效提升訪問量,顯著降低帶寬占用,減輕原始服務器的繁忙度,加快響應速度,毋須不停地購置大內存,大硬盤,擴容電力設施為服務器端節省成本。
頁面片段緩存 (Edge Side Includes,ESI)是一個基于XML的標記語言,目的是在HTTP中組裝各種資源。在實際環境中,一個動態生成的頁面,當中可能只有少量的內容是頻繁變化的或是個性化的,對于傳統的Cache服務器來說,由于這些少量的動態內容的存在,因此無法在保證頁面時效性的前提下將整個頁面進行緩存。ESI通過使用簡單的標記語言來對那些可以緩存和不能緩存的網頁中的內容片斷進行描述,每個網頁都被劃分成不同的小部分分別賦予不同的緩存控制策略,使Cache服務器可以根據這些策略在將完整的網頁發送給用戶之前將不同的小部分動態地組合在一起。通過這種控制,可以有效地減少從服務器抓取整個頁面的次數,而只用從原服務器中提取少量的不能緩存的片斷,因此可以有效降低原服務器的負載,同時提高用戶訪問的響應時間。
本地數據緩存(Local Data Cache):通常包括關系數據庫系統(如:Oracle/MySql)緩存和應用服務器緩存。數據庫系統緩存的重點一般是查詢緩存(以sql為key來緩存查詢結果)和數據緩沖(數據庫數據內存緩存器,其訪問命中率決定數據庫性能);應用服務器Cache包括:對象緩存(例如:對象線程安全,做成單例),更新頻率不大數據考慮緩存(如:基表數據、配置文件信息),考慮使用線程池,對象池,連接池等。
4 結束語
網站架構的設計往往承受著技術、成本和效益等多重因素的制約,而不可能單純考慮某一個設計原則。例如,在互聯網應用中,基于成本和效率的要求,不能單純考慮ACID原則達到數據的強一致性,而通常以BASE策略放棄對強一致性的追求而只強調最終一致性,由此獲得更好的可用性。
另一方面,雖然良好的架構設計往往可以帶來系統性能的躍升,但在架構設計和調整中通常伴隨高昂的人力資源成本。因此在某些情況下簡單的對系統硬件設備進行升級反而可以取得更好的實踐效果。
參考文獻
[1]Peter Morville Louis Rosenfeld, 陳建勛譯.Web信息架構:設計大型網站[M].北京:電子工業出版社,2008,392.
[2]王瑩.網站架構的優化[J].科技傳播,2011(9):223-224.