網站架構

 

大型網站架構演變和知識體系

以前也有一些介紹大型網站架構演變的文章,例如LiveJournal的、ebay的,都是很是值得參考的,不過感受他們講的更多的是每次演變的結果,而沒有很詳細的講爲何須要作這樣的演變,再加上近來感受有很多同窗都很難明白爲何一個網站須要那麼複雜的技術,因而有了寫這篇文章的想法,在這篇文章中 將闡述一個普通的網站發展成大型網站過程當中的一種較爲典型的架構演變歷程和所需掌握的知識體系,但願能給想從事互聯網行業的同窗一點初步的概念,:),文中的不對之處也請各位多給點建議,讓本文真正起到拋磚引玉的效果。

html

架構演變第一步:物理分離webserver和數據庫前端

最開始,因爲某些想法,因而在互聯網上搭建了一個網站,這個時候甚至有可能主機都是租借的,但因爲這篇文章咱們只關注架構的演變歷程,所以就假設這個時候已是託管了一臺主機,而且有必定的帶寬了,這個時候因爲網站具有了必定的特點,吸引了部分人訪問,逐漸你發現系統的壓力愈來愈高,響應速度愈來愈慢,而這個時候比較明顯的是數據庫和應用互相影響,應用出問題了,數據庫也很容易出現問題,而數據庫出問題的時候,應用也容易出問題,因而進入了第一步演變階段:將應用和數據庫從物理上分離,變成了兩臺機器,這個時候技術上沒有什麼新的要求,但你發現確實起到效果了,系統又恢復到之前的響應速度了,而且支撐住了更高的流量,而且不會由於數據庫和應用造成互相的影響。java

看看這一步完成後系統的圖示:linux

 

這一步涉及到了這些知識體系:web

這一步架構演變對技術上的知識體系基本沒有要求。

算法

架構演變第二步:增長頁面緩存數據庫

好景不長,隨着訪問的人愈來愈多,你發現響應速度又開始變慢了,查找緣由,發現是訪問數據庫的操做太多,致使數據鏈接競爭激烈,因此響應變慢,但數據庫鏈接又不能開太多,不然數據庫機器壓力會很高,所以考慮採用緩存機制來減小數據庫鏈接資源的競爭和對數據庫讀的壓力,這個時候首先也許會選擇採用squid 等相似的機制來將系統中相對靜態的頁面(例如一兩天才會有更新的頁面)進行緩存(固然,也能夠採用將頁面靜態化的方案),這樣程序上能夠不作修改,就可以 很好的減小對webserver的壓力以及減小數據庫鏈接資源的競爭,OK,因而開始採用squid來作相對靜態的頁面的緩存。apache

看看這一步完成後系統的圖示:緩存

 

這一步涉及到了這些知識體系:安全

前端頁面緩存技術,例如squid,如想用好的話還得深刻掌握下squid的實現方式以及緩存的失效算法等。

 

架構演變第三步:增長頁面片斷緩存

增長了squid作緩存後,總體系統的速度確實是提高了,webserver的壓力也開始降低了,但隨着訪問量的增長,發現系統又開始變的有些慢了,在嘗 到了squid之類的動態緩存帶來的好處後,開始想能不能讓如今那些動態頁面裏相對靜態的部分也緩存起來呢,所以考慮採用相似ESI之類的頁面片斷緩存策略,OK,因而開始採用ESI來作動態頁面中相對靜態的片斷部分的緩存。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

頁面片斷緩存技術,例如ESI等,想用好的話一樣須要掌握ESI的實現方式等;

 

架構演變第四步:數據緩存

在採用ESI之類的技術再次提升了系統的緩存效果後,系統的壓力確實進一步下降了,但一樣,隨着訪問量的增長,系統仍是開始變慢,通過查找,可能會發現系 統中存在一些重複獲取數據信息的地方,像獲取用戶信息等,這個時候開始考慮是否是能夠將這些數據信息也緩存起來呢,因而將這些數據緩存到本地內存,改變完畢後,徹底符合預期,系統的響應速度又恢復了,數據庫的壓力也再度下降了很多。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

緩存技術,包括像Map數據結構、緩存算法、所選用的框架自己的實現機制等。

 

架構演變第五步: 增長webserver

好景不長,發現隨着系統訪問量的再度增長,webserver機器的壓力在高峯期會上升到比較高,這個時候開始考慮增長一臺webserver,這也是爲了同時解決可用性的問題,避免單臺的webserver down機的話就無法使用了,在作了這些考慮後,決定增長一臺webserver,增長一臺webserver時,會碰到一些問題,典型的有:
一、如何讓訪問分配到這兩臺機器上,這個時候一般會考慮的方案是Apache自帶的負載均衡方案,或LVS這類的軟件負載均衡方案;
二、如何保持狀態信息的同步,例如用戶session等,這個時候會考慮的方案有寫入數據庫、寫入存儲、cookie或同步session信息等機制等;
三、如何保持數據緩存信息的同步,例如以前緩存的用戶數據等,這個時候一般會考慮的機制有緩存同步或分佈式緩存;
四、如何讓上傳文件這些相似的功能繼續正常,這個時候一般會考慮的機制是使用共享文件系統或存儲等;
在解決了這些問題後,終因而把webserver增長爲了兩臺,系統終因而又恢復到了以往的速度。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

負載均衡技術(包括但不限於硬件負載均衡、軟件負載均衡、負載算法、linux轉發協議、所選用的技術的實現細節等)、主備技術(包括但不限於ARP欺騙、linux heart-beat等)、狀態信息或緩存同步技術(包括但不限於Cookie技術、UDP協議、狀態信息廣播、所選用的緩存同步技術的實現細節等)、共享文件技術(包括但不限於NFS等)、存儲技術(包括但不限於存儲設備等)。

 

架構演變第六步:分庫

享受了一段時間的系統訪問量高速增加的幸福後,發現系統又開始變慢了,此次又是什麼情況呢,通過查找,發現數據庫寫入、更新的這些操做的部分數據庫鏈接的資源競爭很是激烈,致使了系統變慢,這下怎麼辦呢,此時可選的方案有數據庫集羣和分庫策略,集羣方面像有些數據庫支持的並非很好,所以分庫會成爲比較廣泛的策略,分庫也就意味着要對原有程序進行修改,一通修改實現分庫後,不錯,目標達到了,系統恢復甚至速度比之前還快了。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

這一步更多的是須要從業務上作合理的劃分,以實現分庫,具體技術細節上沒有其餘的要求;

但同時隨着數據量的增大和分庫的進行,在數據庫的設計、調優以及維護上須要作的更好,所以對這些方面的技術仍是提出了很高的要求的。

 

架構演變第七步:分表、DAL和分佈式緩存
隨着系統的不斷運行,數據量開始大幅度增加,這個時候發現分庫後查詢仍然會有些慢,因而按照分庫的思想開始作分表的工做,固然,這不可避免的會須要對程序進行一些修改,也許在這個時候就會發現應用本身要關心分庫分表的規則等,仍是有些複雜的,因而萌生可否增長一個通用的框架來實現分庫分表的數據訪問,這個在ebay的架構中對應的就是DAL,這個演變的過程相對而言須要花費較長的時間,固然,也有可能這個通用的框架會等到分表作完後纔開始作,同時,在這個階段可能會發現以前的緩存同步方案出現問題,由於數據量太大,致使如今不太可能將緩存存在本地,而後同步的方式,須要採用分佈式緩存方案了,因而,又是一通考察和折磨,終因而將大量的數據緩存轉移到分佈式緩存上了。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

分表更多的一樣是業務上的劃分,技術上涉及到的會有動態hash算法、consistent hash算法等;

DAL涉及到比較多的複雜技術,例如數據庫鏈接的管理(超時、異常)、數據庫操做的控制(超時、異常)、分庫分表規則的封裝等;

 

架構演變第八步:增長更多的webserver

在作完分庫分表這些工做後,數據庫上的壓力已經降到比較低了,又開始過着天天看着訪問量暴增的幸福生活了,忽然有一天,發現系統的訪問又開始有變慢的趨勢了,這個時候首先查看數據庫,壓力一切正常,以後查看webserver,發現apache阻塞了不少的請求,而應用服務器對每一個請求也是比較快的,看來 是請求數過高致使須要排隊等待,響應速度變慢,這還好辦,通常來講,這個時候也會有些錢了,因而添加一些webserver服務器,在這個添加 webserver服務器的過程,有可能會出現幾種挑戰:
一、Apache的軟負載或LVS軟負載等沒法承擔巨大的web訪問量(請求鏈接數、網絡流量等)的調度了,這個時候若是經費容許的話,會採起的方案是購 買硬件負載,例如F五、Netsclar、Athelon之類的,如經費不容許的話,會採起的方案是將應用從邏輯上作必定的分類,而後分散到不一樣的軟負載集羣中;
二、原有的一些狀態信息同步、文件共享等方案可能會出現瓶頸,須要進行改進,也許這個時候會根據狀況編寫符合網站業務需求的分佈式文件系統等;
在作完這些工做後,開始進入一個看似完美的無限伸縮的時代,當網站流量增長時,應對的解決方案就是不斷的添加webserver。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

到了這一步,隨着機器數的不斷增加、數據量的不斷增加和對系統可用性的要求愈來愈高,這個時候要求對所採用的技術都要有更爲深刻的理解,並須要根據網站的需求來作更加定製性質的產品。

 

架構演變第九步:數據讀寫分離和廉價存儲方案

忽然有一天,發現這個完美的時代也要結束了,數據庫的噩夢又一次出如今眼前了,因爲添加的webserver太多了,致使數據庫鏈接的資源仍是不夠用,而這個時候又已經分庫分表了,開始分析數據庫的壓力情況,可能會發現數據庫的讀寫比很高,這個時候一般會想到數據讀寫分離的方案,固然,這個方案要實現並不 容易,另外,可能會發現一些數據存儲在數據庫上有些浪費,或者說過於佔用數據庫資源,所以在這個階段可能會造成的架構演變是實現數據讀寫分離,同時編寫一些更爲廉價的存儲方案,例如BigTable這種。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

數據讀寫分離要求對數據庫的複製、standby等策略有深刻的掌握和理解,同時會要求具有自行實現的技術;

廉價存儲方案要求對OS的文件存儲有深刻的掌握和理解,同時要求對採用的語言在文件這塊的實現有深刻的掌握。

 

架構演變第十步:進入大型分佈式應用時代和廉價服務器羣夢想時代

通過上面這個漫長而痛苦的過程,終因而再度迎來了完美的時代,不斷的增長webserver就能夠支撐愈來愈高的訪問量了,對於大型網站而言,人氣的重要毋庸置疑,隨着人氣的愈來愈高,各類各樣的功能需求也開始爆發性的增加,這個時候忽然發現,原來部署在webserver上的那個web應用已經很是龐大 了,當多個團隊都開始對其進行改動時,可真是至關的不方便,複用性也至關糟糕,基本是每一個團隊都作了或多或少重複的事情,並且部署和維護也是至關的麻煩, 由於龐大的應用包在N臺機器上覆制、啓動都須要耗費很多的時間,出問題的時候也不是很好查,另一個更糟糕的情況是頗有可能會出現某個應用上的bug就導 致了全站都不可用,還有其餘的像調優很差操做(由於機器上部署的應用什麼都要作,根本就沒法進行鍼對性的調優)等因素,根據這樣的分析,開始痛下決心,將 系統根據職責進行拆分,因而一個大型的分佈式應用就誕生了,一般,這個步驟須要耗費至關長的時間,由於會碰到不少的挑戰:
一、拆成分佈式後須要提供一個高性能、穩定的通訊框架,而且須要支持多種不一樣的通訊和遠程調用方式;
二、將一個龐大的應用拆分須要耗費很長的時間,須要進行業務的整理和系統依賴關係的控制等;
三、如何運維(依賴管理、運行情況管理、錯誤追蹤、調優、監控和報警等)好這個龐大的分佈式應用。
通過這一步,差很少系統的架構進入相對穩定的階段,同時也能開始採用大量的廉價機器來支撐着巨大的訪問量和數據量,結合這套架構以及這麼屢次演變過程吸收的經驗來採用其餘各類各樣的方法來支撐着愈來愈高的訪問量。

看看這一步完成後系統的圖示:

 

這一步涉及到了這些知識體系:

這一步涉及的知識體系很是的多,要求對通訊、遠程調用、消息機制等有深刻的理解和掌握,要求的都是從理論、硬件級、操做系統級以及所採用的語言的實現都有清楚的理解。

運維這塊涉及的知識體系也很是的多,多數狀況下須要掌握分佈式並行計算、報表、監控技術以及規則策略等等。

提及來確實不怎麼費力,整個網站架構的經典演變過程都和上面比較的相似,固然,每步採起的方案,演變的步驟有可能有不一樣,另外,因爲網站的業務不一樣,會有不一樣的專業技術的需求,這篇blog更多的是從架構的角度來說解演變的過程,固然,其中還有不少的技術也未在此說起,像數據庫集羣、數據挖掘、搜索等,但在真實的演變過程當中還會藉助像提高硬件配置、網絡環境、改造操做系統、CDN鏡像等來支撐更大的流量,所以在真實的發展過程當中還會有不少的不一樣,另一個大型網站要作到的遠遠不只僅上面這些,還有像安全、運維、運營、服務、存儲等,要作好一個大型的網站真的很不容易,寫這篇文章更多的是但願可以引出更多大型網站架構演變的介紹,:)。

ps:最後附上幾篇LiveJournal架構演變的文章: 從LiveJournal後臺發展看大規模網站性能優化方法 http://blog.zhangjianfeng.com/article/743     另外從這裏:http://www.danga.com/words/你們能夠找到更多關於如今LiveJournal網站架構的介紹。
相關文章
相關標籤/搜索