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