天天看點

高并發高流量網站架構Web2.0的興起,掀起了網際網路新一輪的網絡創業大潮。以使用者為導向的新網站建設概念,細分了網站功能和使用者群,不僅成功的造就了一大批新生的網站,也極大的友善了上網的人們。但Web2.0以使用者為導向的理念,使得新生的網站有了新的特點——高并發,高流量,資料量大,邏輯複雜等,對網站建設也提出了新的要求。

Web2.0的興起,掀起了網際網路新一輪的網絡創業大潮。以使用者為導向的新網站建設概念,細分了網站功能和使用者群,不僅成功的造就了一大批新生的網站,也極大的友善了上網的人們。但Web2.0以使用者為導向的理念,使得新生的網站有了新的特點——高并發,高流量,資料量大,邏輯複雜等,對網站建設也提出了新的要求。

本文圍繞高并發高流量的網站架構設計問題,主要研究讨論了以下内容:

首先在整個網絡的高度讨論了使用鏡像網站,CDN内容分發網絡等技術對負載均衡帶來的便利及各自的優缺點比較。然後在區域網路層次對第四層交換技術,包括硬體解決方案F5和軟體解決方案LVS,進行了簡單的讨論。接下來在單伺服器層次,本文着重讨論了單台伺服器的Socket優化,硬碟級緩存技術,記憶體級緩存技術,CPU與IO平衡技術(即以運算為主的程式與以資料讀寫為主的程式搭配部署),讀寫分離技術等。在應用層,本文介紹了一些大型網站常用的技術,以及選擇使用該技術的理由。最後,在架構的高度讨論了網站擴容,容錯等問題。

本文以理論與實踐相結合的形式,結合作者實際工作中得到的經驗,具有較廣泛的适用性。

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年底推出了新浪播客服務。新浪播客作為國内門戶網站中第一個微視訊分享服務的網站,依靠新浪網 站及新浪部落格的巨大人氣資源,在推出後不到半年的時間内,取得了巨大的成功:同類網站中上傳視訊數量第一、流量增長最快、使用者數最多[12],所有這些成 績的取得的背後,是巨大的硬體投入,良好的架構支撐和靈活的應用層軟體設計。

Java初進階學習分享,共同學習才是最明智的選擇,喜歡的話可以我的學習群64弍46衣3淩9,或加資料群69似64陸0吧3(進群備注平台名)

2.1 鏡像網站技術

鏡像網站是指将一個完全相同的站點放到幾個 伺服器 上,分别有自己的URL,這些 伺服器 上的網站互相稱為鏡像網站[13]。鏡像網站和主站并沒有太大差别,或者可以視為主站的拷貝。鏡像網站的好處是:如果不能對主站作正常通路(如伺服器故障, 網絡 故障或者網速太慢等),仍能通過鏡像伺服器獲得服務。不便之處是:更新網站内容的時候,需要同時更新多個伺服器;需要使用者記憶超過一個網址,或需要使用者選擇通路多個鏡像網站中的一個,而使用者選擇的,不一定是最優的。在使用者選擇的過程中,缺乏必要的可控性。

在網際網路發展的初期,網際網路上的網站内容很少,而且大都是靜态内容,更新頻率 底。但因為伺服器運算能力低,帶寬小,網速慢,熱門網站的通路壓力還是很大。鏡像網站技術在這種情況下作為一種有效解決方案,被廣泛采用。随着網際網路的發 展,越來越多的網站使用伺服器端腳本動态生成内容,同步更新越來越困難,對可控性要求越來越高,鏡像技術因為不能滿足這類網站的需要,漸漸的淡出了人們的 視線。但有一些大型的軟體下載下傳站,因為符合鏡像網站的條件——下載下傳的内容是靜态的,更新頻率較低,對帶寬,速度要求又比較高,如國外的SourceForge (http://www.SourceForge.net,著名開源軟體托管網站),Fedora(http://fedoraproject.org,RedHat贊助的Linux發行版),國内的華軍軟體園(http://www.onlinedown.net),天空軟體站(http://www.skycn.com)等,還在使用這項技術(圖1)。

在網站建設的過程中,可以根據實際情況,将靜态内容作一些鏡像,以加快通路速度,提升使用者體驗。

2.2 CDN内容分發網絡

CDN的全稱是Content Delivery Network,即内容分發網絡。其目的是通過在現有的網際網路中增加一層新的網絡架構,将網站的内容釋出到最接近使用者的網絡“邊緣”,使使用者可以就近取得 所需的内容,分散伺服器的壓力,解決網際網路擁擠的狀況,提高使用者通路網站的響應速度。進而解決由于網絡帶寬小、使用者通路量大、網點分布不均等原因所造成的 使用者通路網站響應速度慢的問題[14]。

CDN與鏡像網站技術的不同之處在于網站代替使用者去選擇最優的内容伺服器,增強了可控制性。CDN其實是夾在網頁浏覽者和被通路的伺服器中間的一層鏡像或 者說緩存,浏覽者通路時點選的還是伺服器原來的URL位址,但是看到的内容其實是對浏覽者來說最優的一台鏡像伺服器上的頁面緩存内容。這是通過調整伺服器 的域名解析來實作的。使用CDN技術的域名解析伺服器需要維護一個鏡像伺服器清單和一份來訪IP到鏡像伺服器的對應表。當一個使用者的請求到來的時候,根據 使用者的IP,查詢對應表,得到最優的鏡像伺服器的IP位址,傳回給使用者。這裡的最優,需要綜合考慮伺服器的處理能力,帶寬,離通路者的距離遠近等因素。當 某個地方的鏡像網站流量過大,帶寬消耗過快,或者出現伺服器,網絡等故障的時候,可以很友善的設定将使用者的通路轉到另外一個地方(圖2)。這樣就增強了可 控制性。

CDN網絡加速技術也有它的局限性。首先,因為内容更新的時候,需要同步更新多 台鏡像伺服器,是以它也隻适用于内容更新不太頻繁,或者對實時性要求不是很高的網站;其次,DNS解析有緩存,當某一個鏡像網站的通路需要轉移時,主 DNS伺服器更改了IP解析結果,但各地的DNS伺服器緩存更新會滞後一段時間,這段時間内使用者的通路仍然會指向該伺服器,可控制性依然有不足。

目前,國内通路量較高的大型網站如新浪、網易等的資訊頻道,均使用CDN網絡加速技術(圖3),雖然網站的通路量巨大,但無論在什麼地方通路,速度都會很快。但論壇,郵箱等更新頻繁,實時性要求高的頻道,則不适合使用這種技術。

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分擔了大部分連接配接,網站的承壓能力就大大增強了。

藍線表示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.3、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)。

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)。另外,還需要合理設計應用層程式,為以後的需求變更,擴容做好準備。

在每一個層次,都需要考慮容錯的問題,嚴格消除單點故障,做到無論應用層程式錯誤,伺服器軟體錯誤,伺服器硬體錯誤,還是網絡錯誤,都不影響網站服務。

7.2展望

目前Linux環境下有著名的LAMP(Linux+Apache+MySQL+PHP/PERL/PYTHON)網站建設方案,但隻是針對一般的中小網站而言。對于高并發高流量的大型商業網站,還沒有一個完整的,成本效益高的解決方案。除去伺服器,硬碟,帶寬等硬體投資外,還需要花費大量的預算和時間精力在軟體解決方案上。

随着網際網路的持續發展,Web2.0的興起,在可以預見的未來裡,網際網路的使用者 持續增多,提供使用者參與的網站不斷增加,使用者參與的内容日益增長,越來越多的網站的并發量,通路量會達到一個新的高度,這就會促使越來越多的個人,公司以 及研究機構來關注高并發高流量的網站架構問題。就像Web1.0成就了無數中小網站,成就了LAMP一樣,Web2.0注定也會成就一個新的,高效的,成 本較低的解決方案。這個方案應該包括透明的第三方CDN網絡加速服務,價格低廉的第四層甚至更高層網絡交換裝置,優化了網絡性能的作業系統,優化了讀寫性 能,分布式,高可靠的檔案系統,揉合了記憶體,硬碟等各個級别緩存的HTTP伺服器,更為高效的伺服器端腳本解析器,以及封裝了大部分細節的應用層設計架構。

技術的進步永無止境。我們期待網際網路更為美好的明天。

❤提問/互動請留言,可直接在最底右下方"寫留言即可"

❤Java初進階學習分享,共同學習才是最明智的選擇,喜歡的話可以我的學習群64弍46衣3淩9,或加資料群69似64陸0吧3(進群備注平台名)

❤如果覺得寫得不錯請點選“訂閱”,每天更新全新的内容!

❤你們的喜歡和關注就是我最大的動力支撐!!!