Web2.0的興起,掀起了互聯(lián)網(wǎng)新一輪的網(wǎng)絡(luò)創(chuàng)業(yè)大潮。以用戶為導(dǎo)向的新網(wǎng)站建設(shè)概念,細(xì)分了網(wǎng)站功能和用戶群,不僅成功的造就了一大批新生的網(wǎng)站,也極大的方便了上網(wǎng)的人們。但Web2.0以用戶為導(dǎo)向的理念,使得新生的網(wǎng)站有了新的特點(diǎn)——高并發(fā),高流量,數(shù)據(jù)量大,邏輯復(fù)雜等,對網(wǎng)站建設(shè)也提出了新的要求。
本文圍繞高并發(fā)高流量的網(wǎng)站架構(gòu)設(shè)計(jì)問題,主要研究討論了以下內(nèi)容: 首先在整個(gè)網(wǎng)絡(luò)的高度討論了使用鏡像網(wǎng)站,CDN內(nèi)容分發(fā)網(wǎng)絡(luò)等技術(shù)對負(fù)載均衡帶來的便利及各自的優(yōu)缺點(diǎn)比較。然后在局域網(wǎng)層次對第四層交換技術(shù),包括硬件解決方案F5和軟件解決方案LVS,進(jìn)行了簡單的討論。接下來在單服務(wù)器層次,本文著重討論了單臺服務(wù)器的Socket優(yōu)化,硬盤級緩存技術(shù),內(nèi)存級緩存技術(shù),CPU與IO平衡技術(shù)(即以運(yùn)算為主的程序與以數(shù)據(jù)讀寫為主的程序搭配部署),讀寫分離技術(shù)等。在應(yīng)用層,本文介紹了一些大型網(wǎng)站常用的技術(shù),以及選擇使用該技術(shù)的理由。最后,在架構(gòu)的高度討論了網(wǎng)站擴(kuò)容,容錯(cuò)等問題。 本文以理論與實(shí)踐相結(jié)合的形式,結(jié)合作者實(shí)際工作中得到的經(jīng)驗(yàn),具有較廣泛的適用性。 1.2 互聯(lián)網(wǎng)網(wǎng)站建設(shè)的新趨勢 高性能和高可擴(kuò)展性。2000 年 5 月,訪問量排名世界第一(統(tǒng)計(jì)數(shù)據(jù)來源[5])的Yahoo [6]聲稱其日頁瀏覽數(shù)達(dá)到 6 億 2500 萬,即每秒約 30,000 次HTTP 請求(按每個(gè)頁面瀏覽平均產(chǎn)生 4 次請求計(jì)算) 。這樣大規(guī)模的訪問量對服務(wù)的性能提出了非常高的要求。更為重要的是, 互聯(lián)網(wǎng)受眾的廣泛性,使得成功的互聯(lián)網(wǎng)服務(wù)的訪問量增長潛力和速度非常大,因此服務(wù)系統(tǒng)必須具有非常好的可擴(kuò)展性,以應(yīng)付將來可能的服務(wù)增長。 支持高度并發(fā)的訪問。高度并發(fā)的訪問對服務(wù)的存儲(chǔ)與并發(fā)能力提出了很高的要求,當(dāng)前主流的超標(biāo)量和超流水線處理器能處理的并發(fā)請求數(shù)是有限的,因?yàn)殡S著并發(fā)數(shù)的上升,進(jìn)程調(diào)度的開銷會(huì)很快上升?;ヂ?lián)網(wǎng)廣域網(wǎng)的本質(zhì)決定了其訪問的延遲時(shí)間較長,因此一個(gè)請求完成時(shí)間也較長,按從請求產(chǎn)生到頁面下載完成 3 秒計(jì)算, Yahoo 在 2000 年 5 月時(shí)平均有 90,000 個(gè)并發(fā)請求。而且對于較復(fù)雜的服務(wù),服務(wù)器往往要維護(hù)用戶會(huì)話的信息,例如一個(gè)互聯(lián)網(wǎng)網(wǎng)站如果每天有 100 萬次用戶會(huì)話,每次 20分鐘的話,那平均同時(shí)就會(huì)有約 14000 個(gè)并發(fā)會(huì)話。 高可用性?;ヂ?lián)網(wǎng)服務(wù)的全球性決定了其每天 24 小時(shí)都會(huì)有用戶訪問,因此任何服務(wù)的停止都會(huì)對用戶造成影響。而對于電子商務(wù)等應(yīng)用,暫時(shí)的服務(wù)中止則意味著客戶的永久失去及大量的經(jīng)濟(jì)損失,例如ebay.com[7]1999 年 6 月的一次 22小時(shí)的網(wǎng)站不可訪問,對此網(wǎng)站的 380萬用戶的忠誠度造成巨大影響,使得 Ebay 公司不得不支付了近500萬美元用于補(bǔ)償客戶的損失,而該公司的市值同期下降了 40 億美元[8]。因此,關(guān)鍵互聯(lián)網(wǎng)應(yīng)用的可用性要求非常高。 1.3 新浪播客的簡介 2.1 鏡像網(wǎng)站技術(shù) 鏡像網(wǎng)站是指將一個(gè)完全相同的站點(diǎn)放到幾個(gè)服務(wù)器上,分別有自己的URL,這些服務(wù)器上的網(wǎng)站互相稱為鏡像網(wǎng)站[13]。鏡像網(wǎng)站和主站并沒有太大差別,或者可以視為主站的拷貝。鏡像網(wǎng)站的好處是:如果不能對主站作正常訪問(如服務(wù)器故障,網(wǎng)絡(luò)故障或者網(wǎng)速太慢等),仍能通過鏡像服務(wù)器獲得服務(wù)。不便之處是:更新網(wǎng)站內(nèi)容的時(shí)候,需要同時(shí)更新多個(gè)服務(wù)器;需要用戶記憶超過一個(gè)網(wǎng)址,或需要用戶選擇訪問多個(gè)鏡像網(wǎng)站中的一個(gè),而用戶選擇的,不一定是最優(yōu)的。在用戶選擇的過程中,缺乏必要的可控性。 在互聯(lián)網(wǎng)發(fā)展的初期,互聯(lián)網(wǎng)上的網(wǎng)站內(nèi)容很少,而且大都是靜態(tài)內(nèi)容,更新頻率底。但因?yàn)榉?wù)器運(yùn)算能力低,帶寬小,網(wǎng)速慢,熱門網(wǎng)站的訪問壓力還是很大。鏡像網(wǎng)站技術(shù)在這種情況下作為一種有效解決方案,被廣泛采用。隨著互聯(lián)網(wǎng)的發(fā)展,越來越多的網(wǎng)站使用服務(wù)器端腳本動(dòng)態(tài)生成內(nèi)容,同步更新越來越困難,對可控性要求越來越高,鏡像技術(shù)因?yàn)椴荒軡M足這類網(wǎng)站的需要,漸漸的淡出了人們的視線。但有一些大型的軟件下載站,因?yàn)榉乡R像網(wǎng)站的條件——下載的內(nèi)容是靜態(tài)的,更新頻率較低,對帶寬,速度要求又比較高,如國外的SourceForge (http://www.SourceForge.net,著名開源軟件托管網(wǎng)站),F(xiàn)edora(http://,RedHat贊助的Linux發(fā)行版),國內(nèi)的華軍軟件園(http://www.onlinedown.net),天空軟件站(http://www.)等,還在使用這項(xiàng)技術(shù)(圖1)。
下圖:SourceForge下載時(shí)的鏡像選擇頁面 在網(wǎng)站建設(shè)的過程中,可以根據(jù)實(shí)際情況,將靜態(tài)內(nèi)容作一些鏡像,以加快訪問速度,提升用戶體驗(yàn)。 2.2 CDN內(nèi)容分發(fā)網(wǎng)絡(luò) CDN與鏡像網(wǎng)站技術(shù)的不同之處在于網(wǎng)站代替用戶去選擇最優(yōu)的內(nèi)容服務(wù)器,增強(qiáng)了可控制性。CDN其實(shí)是夾在網(wǎng)頁瀏覽者和被訪問的服務(wù)器中間的一層鏡像或者說緩存,瀏覽者訪問時(shí)點(diǎn)擊的還是服務(wù)器原來的URL地址,但是看到的內(nèi)容其實(shí)是對瀏覽者來說最優(yōu)的一臺鏡像服務(wù)器上的頁面緩存內(nèi)容。這是通過調(diào)整服務(wù)器的域名解析來實(shí)現(xiàn)的。使用CDN技術(shù)的域名解析服務(wù)器需要維護(hù)一個(gè)鏡像服務(wù)器列表和一份來訪IP到鏡像服務(wù)器的對應(yīng)表。當(dāng)一個(gè)用戶的請求到來的時(shí)候,根據(jù)用戶的IP,查詢對應(yīng)表,得到最優(yōu)的鏡像服務(wù)器的IP地址,返回給用戶。這里的最優(yōu),需要綜合考慮服務(wù)器的處理能力,帶寬,離訪問者的距離遠(yuǎn)近等因素。當(dāng)某個(gè)地方的鏡像網(wǎng)站流量過大,帶寬消耗過快,或者出現(xiàn)服務(wù)器,網(wǎng)絡(luò)等故障的時(shí)候,可以很方便的設(shè)置將用戶的訪問轉(zhuǎn)到另外一個(gè)地方(圖2)。這樣就增強(qiáng)了可控制性。
CDN網(wǎng)絡(luò)加速技術(shù)也有它的局限性。首先,因?yàn)閮?nèi)容更新的時(shí)候,需要同步更新多臺鏡像服務(wù)器,所以它也只適用于內(nèi)容更新不太頻繁,或者對實(shí)時(shí)性要求不是很高的網(wǎng)站;其次,DNS解析有緩存,當(dāng)某一個(gè)鏡像網(wǎng)站的訪問需要轉(zhuǎn)移時(shí),主DNS服務(wù)器更改了IP解析結(jié)果,但各地的DNS服務(wù)器緩存更新會(huì)滯后一段時(shí)間,這段時(shí)間內(nèi)用戶的訪問仍然會(huì)指向該服務(wù)器,可控制性依然有不足。 目前,國內(nèi)訪問量較高的大型網(wǎng)站如新浪、網(wǎng)易等的資訊頻道,均使用CDN網(wǎng)絡(luò)加速技術(shù)(圖3),雖然網(wǎng)站的訪問量巨大,但無論在什么地方訪問,速度都會(huì)很快。但論壇,郵箱等更新頻繁,實(shí)時(shí)性要求高的頻道,則不適合使用這種技術(shù)。
ChinaCache的服務(wù)節(jié)點(diǎn)全球超過130個(gè), 其中中國節(jié)點(diǎn)超過80個(gè), 覆蓋全國主要6大網(wǎng)絡(luò)的主要省份[15]。 2.3 應(yīng)用層分布式設(shè)計(jì) 2.4 網(wǎng)絡(luò)層架構(gòu)小結(jié) 3 交換層架構(gòu) 3.1 第四層交換簡介 按照OSI[16]七層模型,第四層是傳輸層。傳輸層負(fù)責(zé)端到端通信,在IP協(xié)議棧中是TCP和UDP所在的協(xié)議層。TCP和UDP數(shù)據(jù)包中包含端口號(port number),它們可以唯一區(qū)分每個(gè)數(shù)據(jù)包所屬的協(xié)議和應(yīng)用程序。接收端計(jì)算機(jī)的操作系統(tǒng)根據(jù)端口號確定所收到的IP包類型,并把它交給合適的高層程序。IP地址和端口號的組合通常稱作“插口(Socket)”。 第四層交換的一個(gè)簡單定義是:它是一種傳輸功能,它決定傳輸不僅僅依據(jù)MAC地址(第二層網(wǎng)橋)或源/目標(biāo)IP地址(第三層路由),而且依據(jù)IP地址與TCP/UDP (第四層) 應(yīng)用端口號的組合(Socket)[17]。第四層交換功能就像是虛擬IP,指向?qū)嶋H的服務(wù)器。它傳輸?shù)臄?shù)據(jù)支持多種協(xié)議,有HTTP、FTP、NFS、Telnet等。 以HTTP協(xié)議為例,在第四層交換中為每個(gè)服務(wù)器組設(shè)立一個(gè)虛擬IP(Virtue IP,VIP),每組服務(wù)器支持某一個(gè)或幾個(gè)域名。在域名服務(wù)器(DNS)中存儲(chǔ)服務(wù)器組的VIP,而不是某一臺服務(wù)器的真實(shí)地址。 當(dāng)用戶請求頁面時(shí),一個(gè)帶有目標(biāo)服務(wù)器組的VIP連接請求發(fā)送給第四層交換機(jī)。第四層交換機(jī)使用某種選擇策略,在組中選取最優(yōu)的服務(wù)器,將數(shù)據(jù)包中的目標(biāo)VIP地址用實(shí)際服務(wù)器的IP地址取代,并將連接請求傳給該服務(wù)器。第四層交換一般都實(shí)現(xiàn)了會(huì)話保持功能,即同一會(huì)話的所有的包由第四層交換機(jī)進(jìn)行映射后,在用戶和同一服務(wù)器間進(jìn)行傳輸[18]。 第四層交換按實(shí)現(xiàn)分類,分為硬件實(shí)現(xiàn)和軟件實(shí)現(xiàn)。 3.2 硬件實(shí)現(xiàn) 3.3 軟件實(shí)現(xiàn) 4 服務(wù)器優(yōu)化 4.1 服務(wù)器整體性能考慮 對于價(jià)值昂貴的服務(wù)器來說,怎樣配置才能發(fā)揮它的最大功效,又不至于影響正常的服務(wù),這是在設(shè)計(jì)網(wǎng)站架構(gòu)的時(shí)候必須要考慮的。常見的影響服務(wù)器的處理速度的因素有:網(wǎng)絡(luò)連接,硬盤讀寫,內(nèi)存空間,CPU速度。如果服務(wù)器的某一個(gè)部件滿負(fù)荷運(yùn)轉(zhuǎn)仍然低于需要,而其他部件仍有能力剩余,我們將之稱為性能瓶頸。服務(wù)器想要發(fā)揮最大的功效,關(guān)鍵的是消除瓶頸,讓所有的部件都被充分的利用起來。 4.2 Socket優(yōu)化 /proc/sys/net/ipv4/tcp_window_scaling “1”(1表示啟用該選項(xiàng),0表示關(guān)閉,下同) 啟用 RFC[25] 1323[26] 定義的 window scaling;要支持超過 64KB 的窗口,必須啟用該值。 /proc/sys/net/ipv4/tcp_sack “1”啟用有選擇的應(yīng)答(Selective Acknowledgment),通過有選擇地應(yīng)答亂序接收到的報(bào)文來提高性能(這樣可以讓發(fā)送者只發(fā)送丟失的報(bào)文段);對于廣域網(wǎng)通信來說,這個(gè)選項(xiàng)應(yīng)該啟用,但是這也會(huì)增加對 CPU 的占用。 /proc/sys/net/ipv4/tcp_timestamps “1” 以一種比重發(fā)超時(shí)更精確的方法(參閱 RFC 1323)來啟用對 RTT 的計(jì)算;為了實(shí)現(xiàn)更好的性能應(yīng)該啟用這個(gè)選項(xiàng)。 /proc/sys/net/ipv4/tcp_mem “24576 32768 49152” 確定 TCP 棧應(yīng)該如何反映內(nèi)存使用;每個(gè)值的單位都是內(nèi)存頁(通常是 4KB)。第一個(gè)值是內(nèi)存使用的下限。第二個(gè)值是內(nèi)存壓力模式開始對緩沖區(qū)使用應(yīng)用壓力的上限。第三個(gè)值是內(nèi)存上限。超過這個(gè)上限時(shí)可以將報(bào)文丟棄,從而減少對內(nèi)存的使用。 /proc/sys/net/ipv4/tcp_wmem “4096 16384 131072” 為自動(dòng)調(diào)優(yōu)定義每個(gè) socket 使用的內(nèi)存。第一個(gè)值是為 socket 的發(fā)送緩沖區(qū)分配的最少字節(jié)數(shù)。第二個(gè)值是默認(rèn)值(該值會(huì)被 wmem_default 覆蓋),緩沖區(qū)在系統(tǒng)負(fù)載不重的情況下可以增長到這個(gè)值。第三個(gè)值是發(fā)送緩沖區(qū)空間的最大字節(jié)數(shù)(該值會(huì)被 wmem_max 覆蓋)。 /proc/sys/net/ipv4/tcp_westwood “1” 啟用發(fā)送者端的擁塞控制算法,它可以維護(hù)對吞吐量的評估,并試圖對帶寬的整體利用情況進(jìn)行優(yōu)化;對于 WAN 通信來說應(yīng)該啟用這個(gè)選項(xiàng)。 與其他調(diào)優(yōu)努力一樣,最好的方法實(shí)際上就是不斷進(jìn)行實(shí)驗(yàn)。具體應(yīng)用程序的行為、處理器的速度以及可用內(nèi)存的多少都會(huì)影響到這些參數(shù)對性能作用的效果。在某些情況中,一些認(rèn)為有益的操作可能恰恰是有害的(反之亦然)。因此,需要逐一試驗(yàn)各個(gè)選項(xiàng),然后檢查每個(gè)選項(xiàng)的結(jié)果,最后得出最適合具體機(jī)器的一套參數(shù)。 如果重啟了 GNU/Linux 系統(tǒng),設(shè)置的內(nèi)核參數(shù)都會(huì)恢復(fù)成默認(rèn)值。為了將所設(shè)置的值作為這些參數(shù)的默認(rèn)值,可以使用 /etc/rc.local 文件,在系統(tǒng)每次啟動(dòng)時(shí)自動(dòng)將這些參數(shù)配置成所需要的值。 在檢測每個(gè)選項(xiàng)的更改帶來的效果的時(shí)候,GNU/Linux上有一些非常強(qiáng)大的工具可以使用: ping 這是用于檢查主機(jī)的可用性的最常用的工具,也可以用于計(jì)算網(wǎng)絡(luò)帶寬延時(shí)。 traceroute 打印連接到特定網(wǎng)絡(luò)主機(jī)所經(jīng)過的一系列路由器和網(wǎng)關(guān)的路徑(路由),從而確定每個(gè) hop 之間的延時(shí)。 netstat 確定有關(guān)網(wǎng)絡(luò)子系統(tǒng)、協(xié)議和連接的各種統(tǒng)計(jì)信息。 tcpdump 顯示一個(gè)或多個(gè)連接的協(xié)議級的報(bào)文跟蹤信息,其中包括時(shí)間信息,可以使用這些信息來研究不同協(xié)議的報(bào)文時(shí)間。 Ethereal 以一個(gè)易于使用的圖形化界面提供 tcpump (報(bào)文跟蹤)的信息,支持報(bào)文過濾功能。 iperf 測量 TCP 和 UDP 的網(wǎng)絡(luò)性能;測量最大帶寬,并匯報(bào)延時(shí)和數(shù)據(jù)報(bào)的丟失情況。 4.3 硬盤級緩存 Squid是一個(gè)高性能的代理緩存服務(wù)器。和一般的代理緩存軟件不同,Squid用一個(gè)單獨(dú)的、非模塊化的、I/O驅(qū)動(dòng)的進(jìn)程來處理所有的客戶端請求。它接受來自客戶端對目標(biāo)對象的請求并適當(dāng)?shù)靥幚磉@些請求。比如說,用戶通過瀏覽器想下載(即瀏覽)一個(gè)web頁面,瀏覽器請求Squid為它取得這個(gè)頁面。Squid隨之連接到頁面所在的原始服務(wù)器并向服務(wù)器發(fā)出取得該頁面的請求。取得頁面后,Squid再將頁面返回給用戶端瀏覽器,并且同時(shí)在Squid本地緩存目錄里保存一份副本。當(dāng)下一次有用戶需要同一頁面時(shí),Squid可以簡單地從緩存中讀取它的副本,直接返回給用戶,而不用再次請求原始服務(wù)器。當(dāng)前的Squid可以處理HTTP, FTP, GOPHER, SSL和WAIS等協(xié)議。 Squid默認(rèn)通過檢測HTTP協(xié)議頭的Expires和 Cache-Control字段來決定緩存的時(shí)間。在實(shí)際應(yīng)用中,可以顯式的在服務(wù)器端腳本中輸出HTTP頭,也可以通過配置apache的mod_expires模塊,讓apache自動(dòng)的給每一個(gè)網(wǎng)頁加上過期時(shí)間。對于靜態(tài)內(nèi)容,如圖片,視頻文件,供下載的軟件等,還可以針對文件類型(擴(kuò)展名),用 Squid 的 refresh_pattern 來指定緩存時(shí)間。 Squid 運(yùn)行的時(shí)候,默認(rèn)會(huì)在硬盤上建兩層hash目錄,用來存儲(chǔ)緩存的Object。它還會(huì)在內(nèi)存中建立一個(gè)Hash Table,用來記錄硬盤中Object分布的情況。如果Squid配置成為一個(gè)Squid集群中的一個(gè)的話,它還會(huì)建立一個(gè) Digest Table(摘要表),用來存儲(chǔ)其它 Squid 上的Object摘要。當(dāng)用戶端想要的資料本地硬盤上沒有時(shí),可以很快的知道應(yīng)該去集群中的哪一臺機(jī)器獲得。在硬盤空間快要達(dá)到配置限額的時(shí)候,可以配置使用某種策略(默認(rèn)使用LRU:Least Recently Used-最近最少用)刪除一些Object,從而騰出空間[28][29]。 集群中的Squid Server 之間可以有兩種關(guān)系:第一種關(guān)系是:Child 和 Parent。當(dāng) Child Squid Server 沒有資料時(shí),會(huì)直接向 Parent Squid Server 要資料,然后一直等,直到 Parent 給它資料為止。 第二種關(guān)系是:Sibling 和 Sibling。當(dāng) Squid Server 沒有資料時(shí),會(huì)先向 Sibling 的 Squid Server 要資料,如果 Sibling 沒資料,就跳過它向 Parent 要或直接上原始網(wǎng)站去拿。 默認(rèn)配置的Squid,沒有經(jīng)過任何優(yōu)化的時(shí)候,一般可以達(dá)到 50% 的命中率[30](圖4)。如果需要,還可以通過參數(shù)優(yōu)化,拆分業(yè)務(wù),優(yōu)化文件系統(tǒng)等辦法,使得Squid達(dá)到 90% 以上的緩存命中率。 Squid處理TCP連接消耗的服務(wù)器資源比真正的HTTP服務(wù)器要小的多,當(dāng)Squid分擔(dān)了大部分連接,網(wǎng)站的承壓能力就大大增強(qiáng)了。
藍(lán)線表示Squid的流量,綠色部分表示Apache流量 4.4 內(nèi)存級緩存 Memcached是danga.com(運(yùn)營Live Journal[32]的技術(shù)團(tuán)隊(duì))開發(fā)的一套非常優(yōu)秀的分布式內(nèi)存對象緩存系統(tǒng),用于在動(dòng)態(tài)系統(tǒng)中減少數(shù)據(jù)庫負(fù)載,提升性能。和 Squid 的前端緩存加速不同,它是通過基于內(nèi)存的對象緩存來減少數(shù)據(jù)庫查詢的方式改善網(wǎng)站的性能,而其中最吸引人的一個(gè)特性就是支持分布式部署;也就是說可以在一群機(jī)器上建立一堆 Memcached 服務(wù),每個(gè)服務(wù)可以根據(jù)具體服務(wù)器的硬件配置使用不同大小的內(nèi)存塊,這樣,理論上可以建立一個(gè)無限大的基于內(nèi)存的緩存系統(tǒng)。 Memcached 是以守護(hù)程序方式運(yùn)行于一個(gè)或多個(gè)服務(wù)器中,隨時(shí)接受客戶端的連接操作,客戶端可以由各種語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等[附錄1]。客戶端首先與 Memcached 服務(wù)建立連接,然后存取對象。每個(gè)被存取的對象都有一個(gè)唯一的標(biāo)識符 key,存取操作均通過這個(gè) key 進(jìn)行,保存的時(shí)候還可以設(shè)置有效期。保存在 Memcached 中的對象實(shí)際上是放置在內(nèi)存中的,而不是在硬盤上。Memcached 進(jìn)程運(yùn)行之后,會(huì)預(yù)申請一塊較大的內(nèi)存空間,自己進(jìn)行管理,用完之后再申請一塊,而不是每次需要的時(shí)候去向操作系統(tǒng)申請。Memcached將對象保存在一個(gè)巨大的Hash表中,它還使用NewHash算法來管理Hash表,從而獲得進(jìn)一步的性能提升。所以當(dāng)分配給Memcached的內(nèi)存足夠大的時(shí)候,Memcached的時(shí)間消耗基本上只是網(wǎng)絡(luò)Socket連接了[33]。 Memcached也有它的不足。首先它的數(shù)據(jù)是保存在內(nèi)存當(dāng)中的,一旦服務(wù)進(jìn)程重啟(進(jìn)程意外被關(guān)掉,機(jī)器重啟等),數(shù)據(jù)會(huì)全部丟失。其次Memcached以root權(quán)限運(yùn)行,而且Memcached本身沒有任何權(quán)限管理和認(rèn)證功能,安全性不足。第一條是Memcached作為內(nèi)存緩存服務(wù)使用無法避免的,當(dāng)然,如果內(nèi)存中的數(shù)據(jù)需要保存,可以采取更改Memcached的源代碼,增加定期寫入硬盤的功能。對于第二條,我們可以將Memcached服務(wù)綁定在內(nèi)網(wǎng)IP上,通過Linux防火墻進(jìn)行防護(hù)。 4.5 CPU與IO均衡 4.6 讀寫分離 一般的文件系統(tǒng),會(huì)綜合考慮各種大小和格式的文件的讀,寫效率,因而對特定的文件讀或?qū)懙男什皇亲顑?yōu)。如果有必要,可以通過選擇文件系統(tǒng),以及修改文件系統(tǒng)的配置參數(shù)來達(dá)到對特定文件的讀或?qū)懙男首畲蠡1热缯f,如果文件系統(tǒng)中需要存儲(chǔ)大量的小文件,則可以使用ReiserFS[37]來替代Linux操作系統(tǒng)默認(rèn)的ext3系統(tǒng),因?yàn)镽eiserFS是基于平衡樹的文件系統(tǒng)結(jié)構(gòu),尤其對于大量文件的巨型文件系統(tǒng),搜索速度要比使用局部的二分查找法的ext3快。 ReiserFS里的目錄是完全動(dòng)態(tài)分配的,因此不存在ext3中常見的無法回收巨型目錄占用的磁盤空間的情況。ReiserFS里小文件(< 4K)可以直接存儲(chǔ)進(jìn)樹,小文件讀取和寫入的速度更快,樹內(nèi)節(jié)點(diǎn)是按字節(jié)對齊的,多個(gè)小文件可共享同一個(gè)硬盤塊,節(jié)約大量空間。ext3使用固定大小的塊分配策略,也就是說,不到4K的小文件也要占據(jù)4K的空間,導(dǎo)致的空間浪費(fèi)比較嚴(yán)重[38]。 但ReiserFS對很多Linux內(nèi)核支持的不是很好,包括2.4.3、2.4.9 甚至相對較新的 2.4.16,如果網(wǎng)站想要使用它,就必須要安裝與它配合的較好的2.4.18內(nèi)核——一般管理員都不是很樂意使用太新的內(nèi)核,因?yàn)樵谒厦孢\(yùn)行的軟件,都還沒有經(jīng)過大量的實(shí)踐測試,也許有一些小的bug還沒有被發(fā)現(xiàn),但對于服務(wù)器來說,再小的bug也是不能接受的。ReiserFS還是一個(gè)較為年輕的,發(fā)展迅速的文件系統(tǒng),它相對于ext3來說有一個(gè)很大的缺陷就是,每次ReiserFS文件系統(tǒng)升級的時(shí)候,必須完全重新格式化整個(gè)磁盤分區(qū)。所以在選擇使用的時(shí)候,需要權(quán)衡取舍[39]。 5 應(yīng)用程序?qū)觾?yōu)化 5.1 網(wǎng)站服務(wù)器程序的選擇 經(jīng)統(tǒng)計(jì)[40],當(dāng)前互聯(lián)網(wǎng)上有超過50%的網(wǎng)站主機(jī)使用Apache[41]服務(wù)器程序。 Apache是開源界的首選Web服務(wù)器,因?yàn)樗膹?qiáng)大和可靠,而且適用于絕大部分的應(yīng)用場合。但是它的強(qiáng)大有時(shí)候卻顯得笨重,配置文件復(fù)雜得讓人望而生畏,高并發(fā)情況下效率不太高。而輕量級的Web服務(wù)器Lighttpd[42]卻是后起之秀,基于單進(jìn)程多路復(fù)用技術(shù),其靜態(tài)文件的響應(yīng)能力遠(yuǎn)高于Apache。 Lighttpd對PHP的支持也很好,還可以通過Fastcgi方式支持其他的語言,比如Python等。 雖然Lighttpd是輕量級的服務(wù)器,功能上不能跟Apache比,某些復(fù)雜應(yīng)用無法勝任,但即使是大部分內(nèi)容動(dòng)態(tài)生成的網(wǎng)站,仍免不了會(huì)有一些靜態(tài)元素,比如圖片、JS腳本、CSS等等,可以考慮將Lighttpd放在Squid的前面,構(gòu)成 Lighttpd->Squid->Apache的一條處理鏈,Lighttpd在最前面,專門處理靜態(tài)內(nèi)容的請求,把動(dòng)態(tài)內(nèi)容請求通過Proxy模塊轉(zhuǎn)發(fā)給Squid,如果Squid中有該請求的內(nèi)容且沒有過期,則直接返回給Lighttpd。新請求或者過期的頁面請求交由Apache中的腳本程序來處理。經(jīng)過Lighttpd和Squid的兩級過濾,Apache需要處理的請求大大減少,減少了Web應(yīng)用程序的壓力。同時(shí)這樣的構(gòu)架,便于把不同的處理分散到多臺計(jì)算機(jī)上進(jìn)行,由Lighttpd在前面統(tǒng)一分發(fā)。 在這種架構(gòu)下,每一級都是可以進(jìn)行單獨(dú)優(yōu)化的,比如Lighttpd可以采用異步IO方式,Squid可以啟用內(nèi)存來緩存,Apache可以啟用MPM(Multi -Processing Modules,多道處理模塊)等,并且每一級都可以使用多臺機(jī)器來均衡負(fù)載,伸縮性好。 著名視頻分享網(wǎng)站YouTube就是選擇使用Lighttpd作為網(wǎng)站的前臺服務(wù)器程序。 5.2 數(shù)據(jù)庫選擇 MySQL數(shù)據(jù)庫能為網(wǎng)站提供: 高性能。MySQL支持海量,快速的數(shù)據(jù)庫存儲(chǔ)和讀取。還可以通過使用64位處理器來獲取額外的一些性能,因?yàn)镸ySQL在內(nèi)部里很多時(shí)候都使用64位的整數(shù)處理。 易用性。MySQL的核心是一個(gè)小而快速的數(shù)據(jù)庫。它的快速連接,快速存取和安全可靠的特性使MySQL非常適合在互聯(lián)網(wǎng)站上使用。 開放性。MySQL提供多種后臺存儲(chǔ)引擎的選擇,如MyISAM, Heap, InnoDB,Berkeley Db等。缺省格式為MyISAM。 MyISAM 存儲(chǔ)引擎與磁盤兼容的非常好[44]。 支持企業(yè)級應(yīng)用。MySQL有一個(gè)用于記錄數(shù)據(jù)改變的二進(jìn)制日志。因?yàn)樗嵌M(jìn)制的,這一日志能夠快速地將數(shù)據(jù)的更改從一臺機(jī)器復(fù)制(replication)到另一臺機(jī)器上。即使服務(wù)器崩潰,這一二進(jìn)制日志也能夠保持完整。這一特性通常被用來搭建數(shù)據(jù)庫集群,以支持更大的流量訪問要求[30](圖5)。 圖
國外的Yahoo!,國內(nèi)的新浪,搜狐等很多大型商業(yè)網(wǎng)站都使用MySQL 作為后臺數(shù)據(jù)庫。對于一般的網(wǎng)站系統(tǒng),無論從成本還是性能上考慮,MySQL應(yīng)該是最佳的選擇。 5.3 服務(wù)器端腳本解析器的選擇 ASP全名Active Server Pages,以及它的升級ASP.NET,是微軟公司出品的一個(gè)WEB服務(wù)器端的開發(fā)環(huán)境,利用它可以產(chǎn)生和運(yùn)行動(dòng)態(tài)的、交互的、高性能的WEB服務(wù)應(yīng)用程序。ASP采用腳本語言VBScript(C#)作為自己的開發(fā)語言。 但因?yàn)橹荒苓\(yùn)行在Windows環(huán)境下,這里我們不討論它。 PHP是一種跨平臺的服務(wù)器端的嵌入式腳本語言。它大量地借用C,Java和Perl語言的語法, 并耦合PHP自己的特性,使WEB開發(fā)者能夠快速地寫出動(dòng)態(tài)生成頁面。它支持目前絕大多數(shù)數(shù)據(jù)庫。PHP也是開源的,它的發(fā)行遵從GPL開源協(xié)議,你可以從 PHP官方站點(diǎn)(http://www.)自由下載到它的二進(jìn)制安裝文件及全部的源代碼。如果在Linux平臺上與MySQL搭配使用,PHP是最佳的選擇。 JSP是Sun公司推出的新一代站點(diǎn)開發(fā)語言,是Java語言除Java應(yīng)用程序和Java Applet之外的第三個(gè)應(yīng)用。Jsp可以在Serverlet和JavaBean的支持下,完成功能強(qiáng)大的站點(diǎn)程序。 作為采用Java技術(shù)家族的一部分,以及Java 2(企業(yè)版體系結(jié)構(gòu))的一個(gè)組成部分,JSP技術(shù)擁有Java技術(shù)帶來的所有優(yōu)點(diǎn),包括優(yōu)秀的跨平臺性,高度可重用的組件設(shè)計(jì),健壯性和安全性等,能夠支持高度復(fù)雜的基于Web的應(yīng)用。 除了這三種常見的腳本之外,在Linux下我們其實(shí)還有很多其他的選擇:Python(Google使用),Perl等,如果作為CGI調(diào)用,那么可選擇范圍就更廣了。使用這些不太常見的腳本語言的好處是,它們對于某些特殊的應(yīng)用有別的腳本所不具有的優(yōu)勢;不好的地方是,這些腳本語言在國內(nèi)使用的人比較少,當(dāng)碰到技術(shù)上的問題的時(shí)候,能找到的資料也較少。 5.4 可配置性 首先,也是最重要的一點(diǎn),功能和展示必須分開。PHP和JSP都支持模板技術(shù),如PHP的Smarty,Phplib,JSP的JSTL(JSP Standard Tag Library)等。核心功能使用腳本語言編寫,前臺展示使用帶特殊標(biāo)簽的HTML,不僅加快了開發(fā)速度,而且方便以后的維護(hù)和升級[47]。 其次,對于前臺模板,一般還需要將頁面的頭,尾單獨(dú)提取出來,頁面的主體部分也按模塊或者功能拆分。對CSS,JS等輔助性的代碼,也建議以單獨(dú)的文件形式存放。這樣不僅方便管理,修改,而且還可以在用戶訪問的時(shí)候進(jìn)行緩存,減少網(wǎng)絡(luò)流量,減輕服務(wù)器壓力。 再次,對于核心功能腳本,必須將與服務(wù)器相關(guān)的配置內(nèi)容,如數(shù)據(jù)庫連接配置,腳本頭文件路徑等,與代碼分離開。尤其當(dāng)網(wǎng)站使用集群技術(shù),CDN加速等技術(shù)的時(shí)候,每一臺服務(wù)器上的配置可能都會(huì)不一樣。如果不使用配置文件,則需要同時(shí)維護(hù)幾份不同的代碼,很容易出錯(cuò)。 最后,應(yīng)該盡量做到修改配置文件后能實(shí)時(shí)生效,避免修改配置文件之后需要重啟服務(wù)程序的情況。 5.5 封裝和中間層思想 在更高的層次,可以將網(wǎng)站分為表示層,邏輯層,持久層,分別進(jìn)行封裝,做到當(dāng)某一層架構(gòu)發(fā)生變化時(shí),不會(huì)影響到其他層。比如新浪播客在一次升級的時(shí)候,將持久層的數(shù)據(jù)庫由原來的集中式改為分布式架構(gòu),因?yàn)榉庋b了數(shù)據(jù)庫連接及所有操作[附錄2],做到了不修改任何上層代碼,平穩(wěn)的實(shí)現(xiàn)了過渡。近來流行的MVC架構(gòu),將整個(gè)網(wǎng)站拆分成Model(模型/邏輯)、View(視圖/界面)、Controller(控制/流程)三個(gè)部分,而且有很多優(yōu)秀的代碼框架可供選擇使用, 像JSP的Structs,Spring,PHP的php.MVC, Studs 等。使用現(xiàn)成的代碼框架,可以使網(wǎng)站開發(fā)事半功倍。 6 擴(kuò)容、容錯(cuò)處理 6.1 擴(kuò)容 一個(gè)大型網(wǎng)站,在設(shè)計(jì)架構(gòu)的時(shí)候,必須考慮到以后可能的容量擴(kuò)充。新浪播客在設(shè)計(jì)時(shí)充分地考慮了這一點(diǎn)。對于視頻分享類網(wǎng)站來說,視頻存儲(chǔ)空間消耗是巨大的。新浪播客在主存儲(chǔ)服務(wù)器上,采用配置文件形式指定每一個(gè)存儲(chǔ)盤柜上存儲(chǔ)的視頻文件的ID范圍。當(dāng)前臺服務(wù)器需要讀取一個(gè)視頻的時(shí)候,首先通過詢問主存儲(chǔ)服務(wù)器上的接口獲得該視頻所在的盤柜及目錄地址,然后再去該盤柜讀取實(shí)際的視頻文件。這樣如果需要增加存儲(chǔ)用的盤柜,只需要修改配置文件即可,前臺程序絲毫不受影響。 新浪播客采用MySQL數(shù)據(jù)庫集群,在邏輯層封裝了所有的數(shù)據(jù)庫連接及操作。當(dāng)數(shù)據(jù)庫存儲(chǔ)架構(gòu)發(fā)生改變的時(shí)候,如增加一臺主庫,將某些數(shù)據(jù)表獨(dú)立成庫,增加讀取數(shù)據(jù)用的從庫等,都只需要修改封裝了的數(shù)據(jù)庫操作類,上層代碼不用修改。 新浪播客的前臺頁面服務(wù)器使用F5公司的硬件第四層交換機(jī),網(wǎng)通,電信分別導(dǎo)向不同的虛擬IP,每一個(gè)虛擬IP后面又有多個(gè)服務(wù)器提供服務(wù)。當(dāng)訪問流量增大的時(shí)候,可以很方便往虛擬IP后面增加服務(wù)器,分擔(dān)壓力。 6.2 容錯(cuò) 2006年12月27日臺灣東部外海發(fā)生里氏7.6級地震,造成途徑臺灣海峽的多條海底電纜中斷,導(dǎo)致許多國外網(wǎng)站,像MSN, NBA, Yahoo?。ㄓ⑽闹髡荆┑葒鴥?nèi)無法訪問,但也有例外,以Google為代表的在國內(nèi)建設(shè)有分布式數(shù)據(jù)節(jié)點(diǎn)的很多網(wǎng)站卻仍然可以訪問。雖然說地震造成斷網(wǎng)是不可抗原因,但如果在這種情況下網(wǎng)站仍然可以訪問,無疑能給網(wǎng)站用戶留下深刻的印象。這件事情給大型商業(yè)網(wǎng)站留下的教訓(xùn)是:網(wǎng)站需要在用戶主要分布區(qū)域保持?jǐn)?shù)據(jù)存在,以防止可能的網(wǎng)絡(luò)故障。 對于服務(wù)器錯(cuò)誤,一般采取冗余設(shè)計(jì)的方法來避免。對于存儲(chǔ)服務(wù)器(主要是負(fù)責(zé)寫入的服務(wù)器),可以使用RAID(冗余磁盤陣列);對于數(shù)據(jù)庫(主要是負(fù)責(zé)寫入的主庫),可以采用雙主庫設(shè)計(jì)[30];對于提供服務(wù)的前臺,則可以使用第四層交換的集群,由多臺服務(wù)器同時(shí)提供服務(wù),不僅分擔(dān)了流量壓力,同時(shí)還可以互相作為備份。 在應(yīng)用層程序中,也要考慮“用戶友好”的出錯(cuò)設(shè)計(jì)。典型例子如HTTP 404 出錯(cuò)頁面,程序內(nèi)部錯(cuò)誤處理,錯(cuò)誤返回提示等,盡可能的做到人性化。 7 總結(jié)及展望 7.1 總結(jié) ![]() 對于一個(gè)高并發(fā)高流量的網(wǎng)站來說,任何一個(gè)環(huán)節(jié)的瓶頸都會(huì)造成網(wǎng)站性能的下降,影響用戶體驗(yàn),進(jìn)而造成巨大的經(jīng)濟(jì)損失。在全互聯(lián)網(wǎng)層面,應(yīng)該使用分布式設(shè)計(jì),縮短網(wǎng)站與用戶的網(wǎng)絡(luò)距離,減少主干網(wǎng)上的流量,以及防止在網(wǎng)絡(luò)意外情況下網(wǎng)站無法訪問的問題。在局域網(wǎng)層面,應(yīng)該使用服務(wù)器集群,一方面可以支撐更大的訪問量,另一方面也作為冗余備份,防止服務(wù)器故障導(dǎo)致的網(wǎng)站無法訪問。在單服務(wù)器層面,應(yīng)該配置操作系統(tǒng),文件系統(tǒng)及應(yīng)用層軟件,均衡各種資源的消耗,消除系統(tǒng)性能瓶頸,充分發(fā)揮服務(wù)器的潛能。在應(yīng)用層,可以通過各種緩存來提升程序的效率,減少服務(wù)器資源消耗(圖6)。另外,還需要合理設(shè)計(jì)應(yīng)用層程序,為以后的需求變更,擴(kuò)容做好準(zhǔn)備。 圖6 典型高并發(fā)高流量網(wǎng)站的架構(gòu) 在每一個(gè)層次,都需要考慮容錯(cuò)的問題,嚴(yán)格消除單點(diǎn)故障,做到無論應(yīng)用層程序錯(cuò)誤,服務(wù)器軟件錯(cuò)誤,服務(wù)器硬件錯(cuò)誤,還是網(wǎng)絡(luò)錯(cuò)誤,都不影響網(wǎng)站服務(wù)。 7.2展望 隨著互聯(lián)網(wǎng)的持續(xù)發(fā)展,Web2.0的興起,在可以預(yù)見的未來里,互聯(lián)網(wǎng)的用戶持續(xù)增多,提供用戶參與的網(wǎng)站不斷增加,用戶參與的內(nèi)容日益增長,越來越多的網(wǎng)站的并發(fā)量,訪問量會(huì)達(dá)到一個(gè)新的高度,這就會(huì)促使越來越多的個(gè)人,公司以及研究機(jī)構(gòu)來關(guān)注高并發(fā)高流量的網(wǎng)站架構(gòu)問題。就像Web1.0成就了無數(shù)中小網(wǎng)站,成就了LAMP一樣,Web2.0注定也會(huì)成就一個(gè)新的,高效的,成本較低的解決方案。這個(gè)方案應(yīng)該包括透明的第三方CDN網(wǎng)絡(luò)加速服務(wù),價(jià)格低廉的第四層甚至更高層網(wǎng)絡(luò)交換設(shè)備,優(yōu)化了網(wǎng)絡(luò)性能的操作系統(tǒng),優(yōu)化了讀寫性能,分布式,高可靠的文件系統(tǒng),揉合了內(nèi)存,硬盤等各個(gè)級別緩存的HTTP服務(wù)器,更為高效的服務(wù)器端腳本解析器,以及封裝了大部分細(xì)節(jié)的應(yīng)用層設(shè)計(jì)框架。 技術(shù)的進(jìn)步永無止境。我們期待互聯(lián)網(wǎng)更為美好的明天 |
|