做大的藝術(shù)–大型網(wǎng)站的架構(gòu)設(shè)計

作者?鄧侃
如果說1980年代是PC的時代,1990年代是互聯(lián)網(wǎng)的時代,那么當下呢?當下是移動互聯(lián)網(wǎng)的時代。移動互聯(lián)網(wǎng)的基本要義,一言以蔽之,就是把手機與網(wǎng)站相連,每部手機在網(wǎng)站上都有獨立的個人空間,成為手機的鏡像。
一部小小的手機里面,可能同時裝載著數(shù)十個軟件。而且在同一時刻,可能好幾個軟件在同時運行。另外,還得時刻準備暫停運行,把手機CPU等資源讓給電話通話等優(yōu)先級別高的工作。還有,時刻需要準備應付網(wǎng)絡(luò)連接中斷,手機電池耗盡等等情況??傊?,手機軟件的結(jié)構(gòu)設(shè)計,是做小的藝術(shù)。
移動網(wǎng)站的架構(gòu)設(shè)計,與手機軟件的架構(gòu)設(shè)計有著本質(zhì)的不同。如果說手機軟件的特點在于小,那么網(wǎng)站的特點在于大。僅中國就有幾億手機用戶,作為服務于移動業(yè)務的網(wǎng)站,它的質(zhì)量來自于是否能夠同時為大規(guī)模并發(fā)用戶提供服務,是否能夠處理海量數(shù)據(jù),是否能夠在需要擴大網(wǎng)站吞吐量的時候,只需要增加機器,而不需要對網(wǎng)站架構(gòu)做大手術(shù)。這是做大的藝術(shù)。
提到做大規(guī)模網(wǎng)站,大家一定會想到云計算,想到Google File System,Chubby, BigTable,MapReduce等等。這些技術(shù)固然很好,但是它們僅僅是構(gòu)成一個大型網(wǎng)站的技術(shù)要素。實際構(gòu)建一個大型網(wǎng)站時,光知道技術(shù)要素是不夠的,還得明白如何把各個要素有機地結(jié)合到一起。
“Flickr 網(wǎng)站架構(gòu)研究”(http://www.ccthere.com/article/2357486)是一篇值得反復閱讀的好文章。這篇文章不僅對一個大型網(wǎng)站的架構(gòu)進行了系統(tǒng)解剖,逐條梳理,而且行文深入淺出。可惜這樣的文章不多見。關(guān)于大型網(wǎng)站實例的討論,散落在各處,而且內(nèi)容零散。
學習和掌握構(gòu)建大型網(wǎng)站的架構(gòu),需要匯總散落的文章,梳理零散的內(nèi)容。做好這項工作很有意義,但是也比較困難。我們的體會是,不妨抓住以下幾個主題,逐個分析大型網(wǎng)站的實例,然后橫向比較。
1. Database
數(shù)據(jù)存儲歷來是麻煩,尤其是需要存儲海量數(shù)據(jù)的時候,往往單個數(shù)據(jù)庫容量不夠,甚至一個數(shù)據(jù)庫集群也不夠。常見的解決辦法是分割,譬如按用戶ID把海量數(shù)據(jù)分割成若干塊,每塊存儲到一個獨立的數(shù)據(jù)庫里去。但是分割的做法降低了join操作的效率。
Google Bigtable的效率如何?好處是什么,缺陷是什么?Bigtable對什么樣的情景最適用?根據(jù)Bigtable原理實現(xiàn)的開源軟件,Hadoop/HBase的運行效率如何?
2. Cache
用戶訪問網(wǎng)站時,通常讀的操作比寫的操作更頻繁。為了提高讀的操作,不妨把相關(guān)內(nèi)容緩存到內(nèi)存里,減少Disk IO的消耗。
MemCached 最近大熱,Wikipedia, YouTube, Digg, Twitter等等大型網(wǎng)站都在用MemCached作為緩存工具。SquidCache和Varnish等等工具,也與緩存沾邊。Twitter的做法是把MemCached和Varnish結(jié)合起來,同時使用。什么樣的內(nèi)容,應該用什么樣的緩存工具?不同的工具間如何協(xié)調(diào)?各大網(wǎng)站的實際運行的結(jié)果,有哪些經(jīng)驗和教訓?
3. File System
有些內(nèi)容,既沒必要存放在數(shù)據(jù)庫里,也不適合存放在緩存中,譬如log 和images。在這種情況下,我們需要文件系統(tǒng)。當有海量內(nèi)容需要存放在文件系統(tǒng)中時,我們需要使用分布式文件系統(tǒng)。Google File System對于什么樣的情景適用,什么樣的情景不適用?分布式文件系統(tǒng)常常需要相應的鎖機制,保證并發(fā)的讀寫操作不相互干擾。Chubby有什么好處?什么情形下不適用?
據(jù)說MogileFS更適合存儲大量的,但是單體尺寸不大的文件,譬如images。而Google File System更適合存放大尺寸但是數(shù)量不多的文件。有沒有可能把小尺寸的多個文件,合并成一個大文件,然后存儲到Google File System中去。在這種情況下,比較MogileFS與Google FS的性能,是否有高下之分?
4. Thread Management
一套工序通常由若干任務組成。多線程的辦法是由一根線程全權(quán)負責整套工序的操作。另外一個辦法是把工序斬成幾段,每一段由一根或幾根線程負責,這種辦法稱為工作臺。
常見的是多線程的辦法。但是工作臺的做法有利于集中計算資源處理繁重的任務,避免瓶頸的出現(xiàn)。但是缺陷是需要在不同線程之間,傳遞記錄中間狀態(tài)的數(shù)據(jù)。什么樣的情形適合用多線程,什么時候用工作臺?
5. Scheduler
同一個網(wǎng)站通常會提供多種服務,不同的服務需要調(diào)用不同的業(yè)務邏輯。有些業(yè)務邏輯可以在同一臺服務器上完成,但是當業(yè)務邏輯復雜的時候,需要調(diào)用多臺服務器合作完成。不同服務的受眾對象不同,流量也不同,不同時段的流量也不同,同一時段不同服務的流量也不同,所以需要動態(tài)地分配計算資源。這是 scheduler的工作。
Scheduler給不同服務器分配工作時,最簡單的辦法是啟動預先安裝在該服務器上的相關(guān)程序。由于不能保證每個程序都十分完美,當一個程序發(fā)生錯誤時,應當避免整個服務器因此而崩潰,影響其它工作的正常進行。是否需要動用virtual machine,實現(xiàn)各個不同工作之間相互隔絕?
6. Signal Flow and Data Flow
大型網(wǎng)站后臺系統(tǒng)經(jīng)常由眾多服務器組成,服務器與服務器之間時不時會發(fā)生數(shù)據(jù)交換,譬如Web Server解析完用戶請求后,把請求轉(zhuǎn)發(fā)給某一臺App Server,這一臺App Server完成了部分工作后,把中間數(shù)據(jù)轉(zhuǎn)發(fā)給下一臺App Server。而第二臺App Server完成任務后,整個工作就結(jié)束了,結(jié)果應該返回給Web Server。
問題是如何讓第一臺App Server如何知道應該把中間結(jié)果給第二臺App Server,而第二臺App Server又如何知道它的目的地是Web Server?一個比較有效率的做法,是區(qū)別數(shù)據(jù)流和控制流。Server與Server之間常設(shè)通道,專供控制流使用,傳遞指令去控制數(shù)據(jù)流的發(fā)送。數(shù)據(jù)流不占用控制流通道,只有在需要時,才建立數(shù)據(jù)流的通道。
控制流和數(shù)據(jù)流的組織,需要結(jié)合具體的業(yè)務邏輯,才能優(yōu)化設(shè)計,減少帶寬消耗,縮短數(shù)據(jù)傳輸?shù)臅r間。
7. Instrumentation
網(wǎng)站后臺各個部分是否運轉(zhuǎn)正常,哪里是瓶頸,哪里空閑。這些都需要實時監(jiān)控。不僅及時避免整個后臺系統(tǒng)的崩潰,而且可以分析各個部分運行的規(guī)律,從而找到優(yōu)化系統(tǒng)的途徑。
問題是,應該選用什么樣的監(jiān)控工具,才能夠盡量減少對系統(tǒng)程序的干擾,同時提供有價值的信息?
8. Anti-abuse
通常網(wǎng)站面對的是形形色色的用戶,絕大多數(shù)用戶的行為是友好的,但是不排除少數(shù)用戶蓄意惡作劇。如果事先沒有設(shè)計防范措施,少數(shù)惡意用戶的胡作非為,會干擾其他用戶享受正常的服務。
問題是,如何防范并且及時制止惡意行為的發(fā)生?
9. Exception Handling
不論預先設(shè)想有多周密,實際運行時,總會遇到這樣那樣的意外情況。譬如敏感詞的出現(xiàn),往往事先沒有征兆。所以,在設(shè)計系統(tǒng)架構(gòu)時,應該給網(wǎng)管提供必要工具,應付突發(fā)事件。
來源:http://www.tektalk.org/2010/03/06/做大的藝術(shù)-大型網(wǎng)站的架構(gòu)設(shè)計/
- 目前還沒評論,等你發(fā)揮!