Web2.0的興起,掀起了互聯網新一輪的網絡創業大潮。以用戶爲導向的新網站建設概念,細分了網站功能和用戶羣,不只成功的造就了一大批新生的網站,也極大的方便了上網的人們。但Web2.0以用戶爲導向的理念,使得新生的網站有了新的特色——高併發,高流量,數據量大,邏輯複雜等,對網站建設也提出了新的要求。php
本文圍繞高併發高流量的網站架構設計問題,主要研究討論瞭如下內容:前端
首先在整個網絡的高度討論了使用鏡像網站,CDN內容分發網絡等技術對負載均衡帶來的便利及各自的優缺點比較。而後在局域網層次對第四層交換技術,包括硬件解決方案F5和軟件解決方案LVS,進行了簡單的討論。接下來在單服務器層次,本文着重討論了單臺服務器的Socket優化,硬盤級緩存技術,內存級緩存技術,CPU與IO平衡技術(即以運算爲主的程序與以數據讀寫爲主的程序搭配部署),讀寫分離技術等。在應用層,本文介紹了一些大型網站經常使用的技術,以及選擇使用該技術的理由。最後,在架構的高度討論了網站擴容,容錯等問題。web
本文以理論與實踐相結合的形式,結合做者實際工做中獲得的經驗,具備較普遍的適用性。算法
關鍵詞:高併發 高流量 網站架構 網站擴容 容錯數據庫
Abstractapache
With web2.0 starting, raised the Internet new turn of network to start undertaking the flood tide. To be user-oriented concept of the new websites, not only successfully created a large number of new sites, but also greatly facilitate the development of the Internet people. The Web2.0 at the same time take the user as the guidance idea, enabled the newborn website to have the new characteristic - high concurrency, high page views, big data quantity, and complex logic , etc. , also set the new request to the website construction. This article revolves the high concurrent high current capacity the website overhead construction design question, the main research discussed these content: First discussed the useage of mirror sites in the entire network, CDN content distribution network, the convenience and respective good and bad points comparison which brings to the load balancing. Then in the local area network, the fourth level exchange technology, including hardware solution F5 and software solution LVS, has been carried on with a simple discussion. Received in the single server level, this article emphatically discussed the single server socket optimization, the hard disk cache technology, the memory level buffer technology, CPU and the IO balance technology , the read-write separation technology and so on. In the application level, this article introduced some large-scale website commonly used technologies, as well as the reason of choice of these technicals. Finally, highly discussed the website in the overhead construction to expand accommodates, fault-tolerant. This article form which unifies by the theory and the practice, experience which in the author practical work obtains, has amore widespread serviceability.瀏覽器
KEY WORDS: high page view, high concurrency, architecture of website site, expansion緩存
目 錄安全
1 引言 9服務器
1.1 互聯網的發展 9
1.2 互聯網網站建設的新趨勢 9
1.3 新浪播客的簡介 11
2 網絡層架構 12
2.1 鏡像網站技術 12
2.2 CDN內容分發網絡 13
2.3 應用層分佈式設計 16
2.4 網絡層架構小結 17
3 交換層架構 17
3.1 第四層交換簡介 17
3.2 硬件實現 18
3.3 軟件實現 18
4 服務器優化 19
4.1 服務器總體性能考慮 19
4.2 Socket優化 19
4.3 硬盤級緩存 22
4.4 內存級緩存 24
4.5 CPU與IO均衡 26
4.6 讀寫分離 26
5 應用程序層優化 28
5.1 網站服務器程序的選擇 28
5.2 數據庫選擇 29
5.3 服務器端腳本解析器的選擇 30
5.4 可配置性 32
5.5 封裝和中間層思想 33
6 擴容、容錯處理 33
6.1 擴容 33
6.2 容錯 34
7 總結及展望 35
7.1 總結 35
7.2 展望 36
1 引言 1.1 互聯網的發展 最近十年間,互聯網已經從一個單純的用於科研的,用來傳遞靜態文檔的美國內部網絡,發展成了一個應用於各行各業的,傳送着海量多媒體及動態信息的全球網絡。從規模上看,互聯網在主機數、帶寬、上網人數等方面幾乎一直保持着指數增加的趨勢,2006年7月,互聯網上共有主機439,286,364臺,WWW 站點數量達到 96,854,877個 [1]。全球上網人口在2004 年達到 7 億 2900萬 [2],中國的上網人數在 2006 年 12 月達到了約 1億3700 萬[3]。另外一方面,互聯網所傳遞的內容也發生了巨大的變化,早期互聯網以靜態、文本的公共信息爲主要內容,而目前的互聯網則傳遞着大量的動態、多媒體及人性化的信息,人們不只能夠經過 互聯網閱讀到動態生成的信息,並且能夠經過它使用電子商務、即時通訊、網上游戲等交互性很強的服務。所以,能夠說互聯網已經再也不僅僅是一個信息共享網絡,而已經成爲了一個無所不在的交互式服務的平臺。
1.2 互聯網網站建設的新趨勢 互聯網不斷擴大的規模,日益增加的用戶羣,以及web2.0[4]的興起,對互聯網網站建設提出了新的要求:
高性能和高可擴展性。2000 年 5 月,訪問量排名世界第一(統計數據來源[5])的Yahoo [6]聲稱其日頁瀏覽數達到 6 億 2500 萬,即每秒約 30,000 次HTTP 請求(按每一個頁面瀏覽平均產生 4 次請求計算) 。這樣大規模的訪問量對服務的性能提出了很是高的要求。更爲重要的是, 互聯網受衆的普遍性,使得成功的互聯網服務的訪問量增加潛力和速度很是大,所以服務系統必須具備很是好的可擴展性,以應付未來可能的服務增加。
支持高度併發的訪問。高度併發的訪問對服務的存儲與併發能力提出了很高的要求,當前主流的超標量和超流水線處理器能處理的併發請求數是有限的,由於隨着併發數的上升,進程調度的開銷會很快上升。互聯網廣域網的本質決定了其訪問的延遲時間較長,所以一個請求完成時間也較長,按從請求產生到頁面下載完成 3 秒計算, Yahoo 在 2000 年 5 月時平均有 90,000 個併發請求。並且對於較複雜的服務,服務器每每要維護用戶會話的信息,例如一個互聯網網站若是天天有 100 萬次用戶會話,每次 20分鐘的話,那平均同時就會有約 14000 個併發會話。
高可用性。互聯網服務的全球性決定了其天天 24 小時都會有用戶訪問,所以任何服務的中止都會對用戶形成影響。而對於電子商務等應用,暫時的服務停止則意味着客戶的永久失去及大量的經濟損失,例如ebay.com[7]1999 年 6 月的一次 22小時的網站不可訪問,對此網站的 380萬用戶的忠誠度形成巨大影響,使得 Ebay 公司不得不支付了近500萬美圓用於補償客戶的損失,而該公司的市值同期降低了 40 億美圓[8]。所以,關鍵互聯網應用的可用性要求很是高。
1.3 新浪播客的簡介 以YouTube[9]爲表明的微視頻分享網站近來方興未艾,僅2006年一年,國內就出現近百家仿YouTube的微視頻分享網站[10],試圖複製YouTube的成功模式。此類網站能夠說是Web2.0概念下的表明網站,具備Web2.0網站全部典型特徵:高併發,高流量,數據量大,邏輯複雜,用戶分散等等。新浪[11]做爲國內最大的門戶網站,在2005年成功運做新浪博客的基礎上,於2006年末推出了新浪播客服務。新浪播客做爲國內門戶網站中第一個微視頻分享服務的網站,依靠新浪網站及新浪博客的巨大人氣資源,在推出後不到半年的時間內,取得了巨大的成功:同類網站中上傳視頻數量第1、流量增加最快、用戶數最多[12],全部這些成績的取得的背後,是巨大的硬件投入,良好的架構支撐和靈活的應用層軟件設計。
本文是做者在新浪愛問搜索部門實習及參與新浪播客開發的經驗和教訓的回顧,是做者對通常高併發高流量網站架構的總結和抽象。
2 網絡層架構 2.1 鏡像網站技術 鏡像網站是指將一個徹底相同的站點放到幾個服務器上,分別有本身的URL,這些服務器上的網站互相稱爲鏡像網站[13]。鏡像網站和主站並無太大差異,或者能夠視爲主站的拷貝。鏡像網站的好處是:若是不能對主站做正常訪問(如服務器故障,網絡故障或者網速太慢等),仍能經過鏡像服務器得到服務。不便之處是:更新網站內容的時候,須要同時更新多個服務器;須要用戶記憶超過一個網址,或須要用戶選擇訪問多個鏡像網站中的一個,而用戶選擇的,不必定是最優的。在用戶選擇的過程當中,缺少必要的可控性。
在互聯網發展的初期,互聯網上的網站內容不多,並且大都是靜態內容,更新頻率底。但由於服務器運算能力低,帶寬小,網速慢,熱門網站的訪問壓力仍是很大。鏡像網站技術在這種狀況下做爲一種有效解決方案,被普遍採用。隨着互聯網的發展,愈來愈多的網站使用服務器端腳本動態生成內容,同步更新愈來愈困難,對可控性要求愈來愈高,鏡像技術由於不能知足這類網站的須要,漸漸的淡出了人們的視線。但有一些大型的軟件下載站,由於符合鏡像網站的條件——下載的內容是靜態的,更新頻率較低,對帶寬,速度要求又比較高,如國外的SourceForge (http://www.SourceForge.net,著名開源軟件託管網站),Fedora(http://fedoraproject.org,RedHat贊助的Linux發行版),國內的華軍軟件園(http://www.onlinedown.net),天空軟件站(http://www.skycn.com)等,還在使用這項技術(圖1)。
圖1 上圖:天空軟件站首頁的鏡像選擇頁面
下圖:SourceForge下載時的鏡像選擇頁面
在網站建設的過程當中,能夠根據實際狀況,將靜態內容做一些鏡像,以加快訪問速度,提高用戶體驗。
2.2 CDN內容分發網絡 CDN的全稱是Content Delivery Network,即內容分發網絡。其目的是經過在現有的互聯網中增長一層新的網絡架構,將網站的內容發佈到最接近用戶的網絡「邊緣」,使用戶能夠就近取得所需的內容,分散服務器的壓力,解決互聯網擁擠的情況,提升用戶訪問網站的響應速度。從而解決因爲網絡帶寬小、用戶訪問量大、網點分佈不均等緣由所形成的用戶訪問網站響應速度慢的問題[14]。
CDN與鏡像網站技術的不一樣之處在於網站代替用戶去選擇最優的內容服務器,加強了可控制性。CDN實際上是夾在網頁瀏覽者和被訪問的服務器中間的一層鏡像或者說緩存,瀏覽者訪問時點擊的仍是服務器原來的URL地址,可是看到的內容實際上是對瀏覽者來講最優的一臺鏡像服務器上的頁面緩存內容。這是經過調整服務器的域名解析來實現的。使用CDN技術的域名解析服務器須要維護一個鏡像服務器列表和一份來訪IP到鏡像服務器的對應表。當一個用戶的請求到來的時候,根據用戶的IP,查詢對應表,獲得最優的鏡像服務器的IP地址,返回給用戶。這裏的最優,須要綜合考慮服務器的處理能力,帶寬,離訪問者的距離遠近等因素。當某個地方的鏡像網站流量過大,帶寬消耗過快,或者出現服務器,網絡等故障的時候,能夠很方便的設置將用戶的訪問轉到另一個地方(圖2)。這樣就加強了可控制性。
圖2 CDN原理示意圖
CDN網絡加速技術也有它的侷限性。首先,由於內容更新的時候,須要同步更新多臺鏡像服務器,因此它也只適用於內容更新不太頻繁,或者對實時性要求不是很高的網站;其次,DNS解析有緩存,當某一個鏡像網站的訪問須要轉移時,主DNS服務器更改了IP解析結果,但各地的DNS服務器緩存更新會滯後一段時間,這段時間內用戶的訪問仍然會指向該服務器,可控制性依然有不足。
目前,國內訪問量較高的大型網站如新浪、網易等的資訊頻道,均使用CDN網絡加速技術(圖3),雖然網站的訪問量巨大,但不管在什麼地方訪問,速度都會很快。但論壇,郵箱等更新頻繁,實時性要求高的頻道,則不適合使用這種技術。
圖3 新浪網使用ChinaCache CDN服務。
ChinaCache的服務節點全球超過130個,
其中中國節點超過80個,
覆蓋全國主要6大網絡的主要省份[15]。
2.3 應用層分佈式設計 新浪播客爲了得到CDN網絡加速的優勢,又必須避免CDN的不足,在應用層軟件設計上,採起了一個替代的辦法。新浪播客提供了一個供播放器查詢視頻文件地址的接口。當用戶打開視頻播放頁面的時候,播放器首先鏈接查詢接口,經過接口得到視頻文件所在的最優的鏡像服務器地址,而後再到該服務器去下載視頻文件。這樣,用一次額外的查詢得到了所有的控制性,而此次查詢的通信流量很是小,幾乎能夠忽略不計。CDN中由域名解析得到的靈活性也保留了下來:由接口程序維護鏡像網站列表及來訪IP到鏡像網站的對應表便可。鏡像網站中不須要鏡像全部的內容,而是隻鏡像更新速度較慢的視頻文件。這是徹底能夠承受的。
2.4 網絡層架構小結 從整個互聯網絡的高度來看網站架構,努力的方向是明確的:讓用戶就近取得內容,但又要在速度和可控制性之間做一個平衡。對於更新比較頻繁內容,因爲難以保持鏡像網站之間的同步,則須要使用其餘的輔助技術。
3 交換層架構 3.1 第四層交換簡介 按照OSI[16]七層模型,第四層是傳輸層。傳輸層負責端到端通訊,在IP協議棧中是TCP和UDP所在的協議層。TCP和UDP數據包中包含端口號(port number),它們能夠惟一區分每一個數據包所屬的協議和應用程序。接收端計算機的操做系統根據端口號肯定所收到的IP包類型,並把它交給合適的高層程序。IP地址和端口號的組合一般稱做「插口(Socket)」。
第四層交換的一個簡單定義是:它是一種傳輸功能,它決定傳輸不只僅依據MAC地址(第二層網橋)或源/目標IP地址(第三層路由),並且依據IP地址與TCP/UDP (第四層) 應用端口號的組合(Socket)[17]。第四層交換功能就像是虛擬IP,指向實際的服務器。它傳輸的數據支持多種協議,有HTTP、FTP、NFS、Telnet等。
以HTTP協議爲例,在第四層交換中爲每一個服務器組設立一個虛擬IP(Virtue IP,VIP),每組服務器支持某一個或幾個域名。在域名服務器(DNS)中存儲服務器組的VIP,而不是某一臺服務器的真實地址。
當用戶請求頁面時,一個帶有目標服務器組的VIP鏈接請求發送給第四層交換機。第四層交換機使用某種選擇策略,在組中選取最優的服務器,將數據包中的目標VIP地址用實際服務器的IP地址取代,並將鏈接請求傳給該服務器。第四層交換通常都實現了會話保持功能,即同一會話的全部的包由第四層交換機進行映射後,在用戶和同一服務器間進行傳輸[18]。
第四層交換按實現分類,分爲硬件實現和軟件實現。
3.2 硬件實現 第四層交換的硬件實現通常都由專業的硬件廠商做爲商業解決方案提供。常見的有Alteon[19],F5[20]等。這些產品很是昂貴,可是可以提供很是優秀的性能和很靈活的管理能力。Yahoo中國當初接近2000臺服務器使用了三四臺Alteon就搞定了[21]。鑑於條件關係,這裏不展開討論。
3.3 軟件實現 第四層交換也能夠經過軟件實現,不過性能比專業硬件稍差,可是知足必定量的壓力仍是能夠達到的,並且軟件實現配置起來更靈活。 軟件四層交換經常使用的有Linux上的LVS(Linux Virtual Server),它提供了基於心跳(heart beat)的實時災難應對解決方案,提升了系統的魯棒性,同時提供了靈活的VIP配置和管理功能,能夠同時知足多種應用需求[22]。
4 服務器優化 4.1 服務器總體性能考慮 對於價值昂貴的服務器來講,怎樣配置才能發揮它的最大功效,又不至於影響正常的服務,這是在設計網站架構的時候必需要考慮的。常見的影響服務器的處理速度的因素有:網絡鏈接,硬盤讀寫,內存空間,CPU速度。若是服務器的某一個部件滿負荷運轉仍然低於須要,而其餘部件仍有能力剩餘,咱們將之稱爲性能瓶頸。服務器想要發揮最大的功效,關鍵的是消除瓶頸,讓全部的部件都被充分的利用起來。
4.2 Socket優化 以標準的 GNU/Linux 爲例。GNU/Linux 發行版試圖對各類部署狀況都進行優化,這意味着對具體服務器的執行環境來講,標準的發行版可能並非最優化的[23]。GNU/Linux 提供了不少可調節的內核參數,可使用這些參數爲服務器進行動態配置,包括影響 Socket 性能的一些重要的選項。這些選項包含在 /proc 虛擬文件系統中。這個文件系統中的每一個文件都表示一個或多個參數,它們能夠經過 cat 工具進行讀取,或使用 echo 命令進行修改。這裏僅列出一些影響TCP/IP 棧性能的可調節內核參數[24]:
/proc/sys/net/ipv4/tcp_window_scaling 「1」(1表示啓用該選項,0表示關閉,下同) 啓用 RFC[25] 1323[26] 定義的 window scaling;要支持超過 64KB 的窗口,必須啓用該值。
/proc/sys/net/ipv4/tcp_sack 「1」啓用有選擇的應答(Selective Acknowledgment),經過有選擇地應答亂序接收到的報文來提升性能(這樣可讓發送者只發送丟失的報文段);對於廣域網通訊來講,這個選項應該啓用,可是這也會增長對 CPU 的佔用。
/proc/sys/net/ipv4/tcp_timestamps 「1」 以一種比重發超時更精確的方法(參閱 RFC 1323)來啓用對 RTT 的計算;爲了實現更好的性能應該啓用這個選項。
/proc/sys/net/ipv4/tcp_mem 「24576 32768 49152」 肯定 TCP 棧應該如何反映內存使用;每一個值的單位都是內存頁(一般是 4KB)。第一個值是內存使用的下限。第二個值是內存壓力模式開始對緩衝區使用應用壓力的上限。第三個值是內存上限。超過這個上限時能夠將報文丟棄,從而減小對內存的使用。
/proc/sys/net/ipv4/tcp_wmem 「4096 16384 131072」 爲自動調優定義每一個 socket 使用的內存。第一個值是爲 socket 的發送緩衝區分配的最少字節數。第二個值是默認值(該值會被 wmem_default 覆蓋),緩衝區在系統負載不重的狀況下能夠增加到這個值。第三個值是發送緩衝區空間的最大字節數(該值會被 wmem_max 覆蓋)。
/proc/sys/net/ipv4/tcp_westwood 「1」 啓用發送者端的擁塞控制算法,它能夠維護對吞吐量的評估,並試圖對帶寬的總體利用狀況進行優化;對於 WAN 通訊來講應該啓用這個選項。
與其餘調優努力同樣,最好的方法實際上就是不斷進行實驗。具體應用程序的行爲、處理器的速度以及可用內存的多少都會影響到這些參數對性能做用的效果。在某些狀況中,一些認爲有益的操做可能偏偏是有害的(反之亦然)。所以,須要逐一試驗各個選項,而後檢查每一個選項的結果,最後得出最適合具體機器的一套參數。
若是重啓了 GNU/Linux 系統,設置的內核參數都會恢復成默認值。爲了將所設置的值做爲這些參數的默認值,可使用 /etc/rc.local 文件,在系統每次啓動時自動將這些參數配置成所須要的值。
在檢測每一個選項的更改帶來的效果的時候,GNU/Linux上有一些很是強大的工具可使用:
ping 這是用於檢查主機的可用性的最經常使用的工具,也能夠用於計算網絡帶寬延時。
traceroute 打印鏈接到特定網絡主機所通過的一系列路由器和網關的路徑(路由),從而肯定每一個 hop 之間的延時。
netstat 肯定有關網絡子系統、協議和鏈接的各類統計信息。
tcpdump 顯示一個或多個鏈接的協議級的報文跟蹤信息,其中包括時間信息,可使用這些信息來研究不一樣協議的報文時間。
Ethereal 以一個易於使用的圖形化界面提供 tcpump (報文跟蹤)的信息,支持報文過濾功能。
iperf 測量 TCP 和 UDP 的網絡性能;測量最大帶寬,並彙報延時和數據報的丟失狀況。
4.3 硬盤級緩存 硬盤級別的緩存是指將須要動態生成的內容暫時緩存在硬盤上,在一個可接受的延遲時間範圍內,一樣的請求再也不動態生成,以達到節約系統資源,提升網站承受能力的目的。Linux環境下硬盤級緩存通常使用Squid[27]。
Squid是一個高性能的代理緩存服務器。和通常的代理緩存軟件不一樣,Squid用一個單獨的、非模塊化的、I/O驅動的進程來處理全部的客戶端請求。它接受來自客戶端對目標對象的請求並適當地處理這些請求。好比說,用戶經過瀏覽器想下載(即瀏覽)一個web頁面,瀏覽器請求Squid爲它取得這個頁面。Squid隨之鏈接到頁面所在的原始服務器並向服務器發出取得該頁面的請求。取得頁面後,Squid再將頁面返回給用戶端瀏覽器,而且同時在Squid本地緩存目錄裏保存一份副本。當下一次有用戶須要同一頁面時,Squid能夠簡單地從緩存中讀取它的副本,直接返回給用戶,而不用再次請求原始服務器。當前的Squid能夠處理HTTP, FTP, GOPHER, SSL和WAIS等協議。
Squid默認經過檢測HTTP協議頭的Expires和 Cache-Control字段來決定緩存的時間。在實際應用中,能夠顯式的在服務器端腳本中輸出HTTP頭,也能夠經過配置apache的mod_expires模塊,讓apache自動的給每個網頁加上過時時間。對於靜態內容,如圖片,視頻文件,供下載的軟件等,還能夠針對文件類型(擴展名),用 Squid 的 refresh_pattern 來指定緩存時間。
Squid 運行的時候,默認會在硬盤上建兩層hash目錄,用來存儲緩存的Object。它還會在內存中創建一個Hash Table,用來記錄硬盤中Object分佈的狀況。若是Squid配置成爲一個Squid集羣中的一個的話,它還會創建一個 Digest Table(摘要表),用來存儲其它 Squid 上的Object摘要。當用戶端想要的資料本地硬盤上沒有時,能夠很快的知道應該去集羣中的哪一臺機器得到。在硬盤空間快要達到配置限額的時候,能夠配置使用某種策略(默認使用LRU:Least Recently Used-最近最少用)刪除一些Object,從而騰出空間[28][29]。
集羣中的Squid Server 之間能夠有兩種關係:第一種關係是:Child 和 Parent。當 Child Squid Server 沒有資料時,會直接向 Parent Squid Server 要資料,而後一直等,直到 Parent 給它資料爲止。 第二種關係是:Sibling 和 Sibling。當 Squid Server 沒有資料時,會先向 Sibling 的 Squid Server 要資料,若是 Sibling 沒資料,就跳過它向 Parent 要或直接上原始網站去拿。
默認配置的Squid,沒有通過任何優化的時候,通常能夠達到 50% 的命中率[30](圖4)。若是須要,還能夠經過參數優化,拆分業務,優化文件系統等辦法,使得Squid達到 90% 以上的緩存命中率。 Squid處理TCP鏈接消耗的服務器資源比真正的HTTP服務器要小的多,當Squid分擔了大部分鏈接,網站的承壓能力就大大加強了。
圖 4 某網站使用MRTG工具檢測到的Squid命中率
藍線表示Squid的流量,綠色部分表示Apache流量
4.4 內存級緩存 內存級別的緩存是指將須要動態生成的內容暫時緩存在內存裏,在一個可接受的延遲時間範圍內,一樣的請求再也不動態生成,而是直接從內存中讀取。Linux環境下內存級緩存Memcached[31]是一個不錯的選擇。
Memcached是danga.com(運營Live Journal[32]的技術團隊)開發的一套很是優秀的分佈式內存對象緩存系統,用於在動態系統中減小數據庫負載,提高性能。和 Squid 的前端緩存加速不一樣,它是經過基於內存的對象緩存來減小數據庫查詢的方式改善網站的性能,而其中最吸引人的一個特性就是支持分佈式部署;也就是說能夠在一羣機器上創建一堆 Memcached 服務,每一個服務能夠根據具體服務器的硬件配置使用不一樣大小的內存塊,這樣,理論上能夠創建一個無限大的基於內存的緩存系統。
Memcached 是以守護程序方式運行於一個或多個服務器中,隨時接受客戶端的鏈接操做,客戶端能夠由各類語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等[附錄1]。客戶端首先與 Memcached 服務創建鏈接,而後存取對象。每一個被存取的對象都有一個惟一的標識符 key,存取操做均經過這個 key 進行,保存的時候還能夠設置有效期。保存在 Memcached 中的對象其實是放置在內存中的,而不是在硬盤上。Memcached 進程運行以後,會預申請一塊較大的內存空間,本身進行管理,用完以後再申請一塊,而不是每次須要的時候去向操做系統申請。Memcached將對象保存在一個巨大的Hash表中,它還使用NewHash算法來管理Hash表,從而得到進一步的性能提高。因此當分配給Memcached的內存足夠大的時候,Memcached的時間消耗基本上只是網絡Socket鏈接了[33]。
Memcached也有它的不足。首先它的數據是保存在內存當中的,一旦服務進程重啓(進程意外被關掉,機器重啓等),數據會所有丟失。其次Memcached以root權限運行,並且Memcached自己沒有任何權限管理和認證功能,安全性不足。第一條是Memcached做爲內存緩存服務使用沒法避免的,固然,若是內存中的數據須要保存,能夠採起更改Memcached的源代碼,增長按期寫入硬盤的功能。對於第二條,咱們能夠將Memcached服務綁定在內網IP上,經過Linux防火牆進行防禦。
4.5 CPU與IO均衡 在一個網站提供的全部功能中,有的功能可能須要消耗大量的服務器端IO資源,像下載,視頻播放等,而有的功能則可能須要消耗大量的服務器CPU資源,像視頻格式轉換,LOG統計等。在一個服務器集羣中,當咱們發現某些機器上CPU和IO的利用率相差很大的時候,例如CPU負載很高而IO負責很低,咱們能夠考慮將該服務器上的某些耗CPU資源的進程換成耗IO的進程,以達到均衡的目的。均衡每一臺機器的CPU和IO消耗,不只能夠得到更充分的服務器資源利用,並且還可以支持暫時的過載,遇到突發事件,訪問流量劇增的時候, 實現得體的性能降低(Graceful performance degradation)[34],而不是當即崩潰。
4.6 讀寫分離 若是網站的硬盤讀寫性能是整個網站性能提高的一個瓶頸的話,能夠考慮將硬盤的讀,寫功能分開,分別進行優化。在專門用來寫的硬盤上,咱們能夠在Linux下使用軟件RAID-0(磁盤冗餘陣列0級)[35]。RAID-0在得到硬盤IO提高的同時,也會增長整個文件系統的故障率——它等於RAID中全部驅動器的故障率之和。若是須要保持或提升硬盤的容錯能力,就須要實現軟件RAID-1,4或5,它們能在某一個(甚至幾個)磁盤驅動器故障以後仍然保持整個文件系統的正常運行[36],但文件讀寫效率不如RAID-0。而專門用來讀的硬盤,則不用如此麻煩,可使用普通的服務器硬盤,以下降開銷。
通常的文件系統,會綜合考慮各類大小和格式的文件的讀,寫效率,於是對特定的文件讀或寫的效率不是最優。若是有必要,能夠經過選擇文件系統,以及修改文件系統的配置參數來達到對特定文件的讀或寫的效率最大化。好比說,若是文件系統中須要存儲大量的小文件,則可使用ReiserFS[37]來替代Linux操做系統默認的ext3系統,由於ReiserFS是基於平衡樹的文件系統結構,尤爲對於大量文件的巨型文件系統,搜索速度要比使用局部的二分查找法的ext3快。 ReiserFS裏的目錄是徹底動態分配的,所以不存在ext3中常見的沒法回收巨型目錄佔用的磁盤空間的狀況。ReiserFS裏小文件(< 4K)能夠直接存儲進樹,小文件讀取和寫入的速度更快,樹內節點是按字節對齊的,多個小文件可共享同一個硬盤塊,節約大量空間。ext3使用固定大小的塊分配策略,也就是說,不到4K的小文件也要佔據4K的空間,致使的空間浪費比較嚴重[38]。 但ReiserFS對不少Linux內核支持的不是很好,包括2.4.三、2.4.9 甚至相對較新的 2.4.16,若是網站想要使用它,就必需要安裝與它配合的較好的2.4.18內核——通常管理員都不是很樂意使用太新的內核,由於在它上面運行的軟件,都尚未通過大量的實踐測試,也許有一些小的bug尚未被發現,但對於服務器來講,再小的bug也是不能接受的。ReiserFS仍是一個較爲年輕的,發展迅速的文件系統,它相對於ext3來講有一個很大的缺陷就是,每次ReiserFS文件系統升級的時候,必須徹底從新格式化整個磁盤分區。因此在選擇使用的時候,須要權衡取捨[39]。
5 應用程序層優化 5.1 網站服務器程序的選擇 經統計[40],當前互聯網上有超過50%的網站主機使用Apache[41]服務器程序。 Apache是開源界的首選Web服務器,由於它的強大和可靠,並且適用於絕大部分的應用場合。可是它的強大有時候卻顯得笨重,配置文件複雜得讓人望而生畏,高併發狀況下效率不過高。而輕量級的Web服務器Lighttpd[42]倒是後起之秀,基於單進程多路複用技術,其靜態文件的響應能力遠高於Apache。 Lighttpd對PHP的支持也很好,還能夠經過Fastcgi方式支持其餘的語言,好比Python等。 雖然Lighttpd是輕量級的服務器,功能上不能跟Apache比,某些複雜應用沒法勝任,但即便是大部份內容動態生成的網站,仍免不了會有一些靜態元素,好比圖片、JS腳本、CSS等等,能夠考慮將Lighttpd放在Squid的前面,構成 Lighttpd->Squid->Apache的一條處理鏈,Lighttpd在最前面,專門處理靜態內容的請求,把動態內容請求經過Proxy模塊轉發給Squid,若是Squid中有該請求的內容且沒有過時,則直接返回給Lighttpd。新請求或者過時的頁面請求交由Apache中的腳本程序來處理。通過Lighttpd和Squid的兩級過濾,Apache須要處理的請求大大減小,減小了Web應用程序的壓力。同時這樣的構架,便於把不一樣的處理分散到多臺計算機上進行,由Lighttpd在前面統一分發。
在這種架構下,每一級都是能夠進行單獨優化的,好比Lighttpd能夠採用異步IO方式,Squid能夠啓用內存來緩存,Apache能夠啓用MPM(Multi -Processing Modules,多道處理模塊)等,而且每一級均可以使用多臺機器來均衡負載,伸縮性好。
著名視頻分享網站YouTube就是選擇使用Lighttpd做爲網站的前臺服務器程序。
5.2 數據庫選擇 MySQL[43]是一個快速的、多線程、多用戶和健壯的SQL數據庫服務器,支持關鍵任務、重負載系統的使用,是最受歡迎的開源數據庫管理系統,是Linux下網站開發的首選。它由MySQL AB開發、發佈和提供支持。
MySQL數據庫能爲網站提供:
高性能。MySQL支持海量,快速的數據庫存儲和讀取。還能夠經過使用64位處理器來獲取額外的一些性能,由於MySQL在內部裏不少時候都使用64位的整數處理。
易用性。MySQL的核心是一個小而快速的數據庫。它的快速鏈接,快速存取和安全可靠的特性使MySQL很是適合在互聯網站上使用。
開放性。MySQL提供多種後臺存儲引擎的選擇,如MyISAM, Heap, InnoDB,Berkeley Db等。缺省格式爲MyISAM。 MyISAM 存儲引擎與磁盤兼容的很是好[44]。
支持企業級應用。MySQL有一個用於記錄數據改變的二進制日誌。由於它是二進制的,這一日誌可以快速地將數據的更改從一臺機器複製(replication)到另外一臺機器上。即便服務器崩潰,這一二進制日誌也可以保持完整。這一特性一般被用來搭建數據庫集羣,以支持更大的流量訪問要求[30](圖5)。
圖 5 MySQL主輔庫模式集羣示意
MySQL也有一些它自身的缺陷,如缺少圖形界面,缺少存儲過程, 還不支持觸發器,參照完整性,子查詢和數據表視圖等,但這些功能都在開發者的TO-DO列表當中。這就是開源的力量:你永遠能夠期待更好。
國外的Yahoo!,國內的新浪,搜狐等不少大型商業網站都使用MySQL 做爲後臺數據庫。對於通常的網站系統,不管從成本仍是性能上考慮,MySQL應該是最佳的選擇。
5.3 服務器端腳本解析器的選擇 目前最多見的服務器端腳本有三種:ASP(Active Server Pages),JSP(Java Server Pages),PHP (Hypertext Preprocessor)[45][46]。
ASP全名Active Server Pages,以及它的升級ASP.NET,是微軟公司出品的一個WEB服務器端的開發環境,利用它能夠產生和運行動態的、交互的、高性能的WEB服務應用程序。ASP採用腳本語言VBScript(C#)做爲本身的開發語言。 但由於只能運行在Windows環境下,這裏咱們不討論它。
PHP是一種跨平臺的服務器端的嵌入式腳本語言。它大量地借用C,Java和Perl語言的語法, 並耦合PHP本身的特性,使WEB開發者可以快速地寫出動態生成頁面。它支持目前絕大多數數據庫。PHP也是開源的,它的發行聽從GPL開源協議,你能夠從 PHP官方站點(http://www.php.net)自由下載到它的二進制安裝文件及所有的源代碼。若是在Linux平臺上與MySQL搭配使用,PHP是最佳的選擇。
JSP是Sun公司推出的新一代站點開發語言,是Java語言除Java應用程序和Java Applet以外的第三個應用。Jsp能夠在Serverlet和JavaBean的支持下,完成功能強大的站點程序。 做爲採用Java技術家族的一部分,以及Java 2(企業版體系結構)的一個組成部分,JSP技術擁有Java技術帶來的全部優勢,包括優秀的跨平臺性,高度可重用的組件設計,健壯性和安全性等,可以支持高度複雜的基於Web的應用。
除了這三種常見的腳本以外,在Linux下咱們其實還有不少其餘的選擇:Python(Google使用),Perl等,若是做爲CGI調用,那麼可選擇範圍就更廣了。使用這些不太常見的腳本語言的好處是,它們對於某些特殊的應用有別的腳本所不具備的優點;很差的地方是,這些腳本語言在國內使用的人比較少,當碰到技術上的問題的時候,能找到的資料也較少。
5.4 可配置性 在大型網站開發過程當中,無論使用什麼技術,網站的可配置性是必須的。在網站的後期運營過程當中,確定會有不少的需求變動。若是每一次的需求變動都會致使修改源代碼,那麼,這個網站的開發能夠說是失敗的。
首先,也是最重要的一點,功能和展現必須分開。PHP和JSP都支持模板技術,如PHP的Smarty,Phplib,JSP的JSTL(JSP Standard Tag Library)等。核心功能使用腳本語言編寫,前臺展現使用帶特殊標籤的HTML,不只加快了開發速度,並且方便之後的維護和升級[47]。
其次,對於前臺模板,通常還須要將頁面的頭,尾單獨提取出來,頁面的主體部分也按模塊或者功能拆分。對CSS,JS等輔助性的代碼,也建議以單獨的文件形式存放。這樣不只方便管理,修改,並且還能夠在用戶訪問的時候進行緩存,減小網絡流量,減輕服務器壓力。
再次,對於核心功能腳本,必須將與服務器相關的配置內容,如數據庫鏈接配置,腳本頭文件路徑等,與代碼分離開。尤爲當網站使用集羣技術,CDN加速等技術的時候,每一臺服務器上的配置可能都會不同。若是不使用配置文件,則須要同時維護幾份不一樣的代碼,很容易出錯。
最後,應該儘可能作到修改配置文件後能實時生效,避免修改配置文件以後須要重啓服務程序的狀況。
5.5 封裝和中間層思想 在功能塊層次,若是使用JSP,基於純面嚮對象語言Java的面向對象思想,相似數據庫鏈接,會話管理等基本功能都已經封裝成類了。若是使用PHP,則須要在腳本代碼中顯式的封裝,將每個功能塊封裝成一個函數,一個文件或者一個類。
在更高的層次,能夠將網站分爲表示層,邏輯層,持久層,分別進行封裝,作到當某一層架構發生變化時,不會影響到其餘層。好比新浪播客在一次升級的時候,將持久層的數據庫由原來的集中式改成分佈式架構,由於封裝了數據庫鏈接及全部操做[附錄2],作到了不修改任何上層代碼,平穩的實現了過渡。近來流行的MVC架構,將整個網站拆分紅Model(模型/邏輯)、View(視圖/界面)、Controller(控制/流程)三個部分,並且有不少優秀的代碼框架可供選擇使用, 像JSP的Structs,Spring,PHP的php.MVC, Studs 等。使用現成的代碼框架,可使網站開發事半功倍。
6 擴容、容錯處理 6.1 擴容 一個大型網站,在設計架構的時候,必須考慮到之後可能的容量擴充。新浪播客在設計時充分地考慮了這一點。對於視頻分享類網站來講,視頻存儲空間消耗是巨大的。新浪播客在主存儲服務器上,採用配置文件形式指定每個存儲盤櫃上存儲的視頻文件的ID範圍。當前臺服務器須要讀取一個視頻的時候,首先經過詢問主存儲服務器上的接口得到該視頻所在的盤櫃及目錄地址,而後再去該盤櫃讀取實際的視頻文件。這樣若是須要增長存儲用的盤櫃,只須要修改配置文件便可,前臺程序絲絕不受影響。
新浪播客採用MySQL數據庫集羣,在邏輯層封裝了全部的數據庫鏈接及操做。當數據庫存儲架構發生改變的時候,如增長一臺主庫,將某些數據表獨立成庫,增長讀取數據用的從庫等,都只須要修改封裝了的數據庫操做類,上層代碼不用修改。
新浪播客的前臺頁面服務器使用F5公司的硬件第四層交換機,網通,電信分別導向不一樣的虛擬IP,每個虛擬IP後面又有多個服務器提供服務。當訪問流量增大的時候,能夠很方便往虛擬IP後面增長服務器,分擔壓力。
6.2 容錯 對於商業性網站來講,可用性是很是重要的。7*24的訪問要求網站具備很強的容錯能力。錯誤包括網絡錯誤,服務器錯誤以及應用程序錯誤。
2006年12月27日臺灣東部外海發生里氏7.6級地震,形成途徑臺灣海峽的多條海底電纜中斷,致使許多國外網站,像MSN, NBA, Yahoo!(英文主站)等國內沒法訪問,但也有例外,以Google爲表明的在國內建設有分佈式數據節點的不少網站卻仍然能夠訪問。雖說地震形成斷網是不可抗緣由,但若是在這種狀況下網站仍然能夠訪問,無疑能給網站用戶留下深入的印象。這件事情給大型商業網站留下的教訓是:網站須要在用戶主要分佈區域保持數據存在,以防止可能的網絡故障。
對於服務器錯誤,通常採起冗餘設計的方法來避免。對於存儲服務器(主要是負責寫入的服務器),可使用RAID(冗餘磁盤陣列);對於數據庫(主要是負責寫入的主庫),能夠採用雙主庫設計[30];對於提供服務的前臺,則可使用第四層交換的集羣,由多臺服務器同時提供服務,不只分擔了流量壓力,同時還能夠互相做爲備份。
在應用層程序中,也要考慮「用戶友好」的出錯設計。典型例子如HTTP 404 出錯頁面,程序內部錯誤處理,錯誤返回提示等,儘量的作到人性化。
7 總結及展望 7.1 總結
對於一個高併發高流量的網站來講,任何一個環節的瓶頸都會形成網站性能的降低,影響用戶體驗,進而形成巨大的經濟損失。在全互聯網層面,應該使用分佈式設計,縮短網站與用戶的網絡距離,減小主幹網上的流量,以及防止在網絡意外狀況下網站沒法訪問的問題。在局域網層面,應該使用服務器集羣,一方面能夠支撐更大的訪問量,另外一方面也做爲冗餘備份,防止服務器故障致使的網站沒法訪問。在單服務器層面,應該配置操做系統,文件系統及應用層軟件,均衡各類資源的消耗,消除系統性能瓶頸,充分發揮服務器的潛能。在應用層,能夠經過各類緩存來提高程序的效率,減小服務器資源消耗(圖6)。另外,還須要合理設計應用層程序,爲之後的需求變動,擴容作好準備。
圖6 典型高併發高流量網站的架構
在每個層次,都須要考慮容錯的問題,嚴格消除單點故障,作到不管應用層程序錯誤,服務器軟件錯誤,服務器硬件錯誤,仍是網絡錯誤,都不影響網站服務。
7.2展望 當前Linux環境下有著名的LAMP(Linux+Apache+MySQL+PHP/PERL/PYTHON)網站建設方案,但只是針對通常的中小網站而言。對於高併發高流量的大型商業網站,尚未一個完整的,性價比高的解決方案。除去服務器,硬盤,帶寬等硬件投資外,還須要花費大量的預算和時間精力在軟件解決方案上。
隨着互聯網的持續發展,Web2.0的興起,在能夠預見的將來裏,互聯網的用戶持續增多,提供用戶參與的網站不斷增長,用戶參與的內容日益增加,愈來愈多的網站的併發量,訪問量會達到一個新的高度,這就會促使愈來愈多的我的,公司以及研究機構來關注高併發高流量的網站架構問題。就像Web1.0成就了無數中小網站,成就了LAMP同樣,Web2.0註定也會成就一個新的,高效的,成本較低的解決方案。這個方案應該包括透明的第三方CDN網絡加速服務,價格低廉的第四層甚至更高層網絡交換設備,優化了網絡性能的操做系統,優化了讀寫性能,分佈式,高可靠的文件系統,揉合了內存,硬盤等各個級別緩存的HTTP服務器,更爲高效的服務器端腳本解析器,以及封裝了大部分細節的應用層設計框架。
技術的進步永無止境。咱們期待互聯網更爲美好的明天。