大型網站架構之:MySpace的體系架構二(轉載)

bq_wang發表於2009-07-19
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE大型網站架構之:MySpace的體系架構()

——

原文連結和影片觀看:

概要

在這次InfoQRyanSlobojan所負責的訪談中,MySpace首席系統架構師DanFarino談論了超大線上社群的系統架構,以及構建這樣一個系統所面臨的各種挑戰。由於幾乎完全基於.NETFramework開發,Dan還解釋了一個.NET平臺下的產品是如何在數百臺伺服器上達到強大伸縮性的。

個人簡介

DanFarinoMySpace.com的首席系統架構師,負責設計和實現用於維護網站數千臺伺服器的基礎架構。Dan設計和實現了許多MySpace.com的自定義效能監視、分析和現場除錯工具。

->大家好,我是RyanSlobojan,這位是MySpaceDanFarinoDan,你能介紹一下你在MySpace的工作嗎?

沒問題。我是MySpace的首席系統架構師。簡單地說,我開發了我們使用的許多後臺自定義效能監視和排錯工具。當初我剛到那裡時,所遇到的問題主要是系統依賴大量的手動配置,大量的手動管理,以及需要大量管理員來建立各種指令碼來執行例如重啟伺服器等工作。你可能要在一個非常簡單的問題上花費30分鐘甚至一個小時的時間。因此,一開始我主要關注於從系統管理的角度出發構建一些自動化工具,希望可以讓排錯或效能診斷等問題變得簡單一些。

->你能否想我們解釋一下,對如此大型的站點進行除錯和排錯時遇到了哪些挑戰呢?

很多時候問題的關鍵在於,如何從幾千臺伺服器中找到出現問題的那臺。所以我開發了一個效能監視系統,可以實時獲取整個伺服器場中每臺機器的CPU、佇列中的請求數以及每秒處理的請求數量等這種型別的資訊。這樣我們就可以直觀地看著螢幕上的一臺紅色的伺服器:喂,我的佇列中累積請求了。然後問題就變成了:好吧,我們已經知道哪臺機器有問題了,不過現在該怎麼做?如果我們獲取一個記憶體快照(memorydump)併傳送給微軟,可能要過一個星期才會有反應說嗨,你們的資料庫伺服器掛了。不過我們希望能在兩個小時內發現這個問題,所以我們在右鍵選單裡放了一些簡單的工具,可以讓一些運維人員——他們不是開發人員——發現說我看到幾百個執行緒在資料庫訪問時阻塞了,我估計是資料庫的問題。我們關注於為出錯的伺服器提供高度視覺化的方案,還開發了一些工具,可以讓一些技術不那麼強的管理員快速發現問題。

->很有意思。你能否從技術角度大致描述一下MySpace的架構呢?

當然。可能從前端開始談這個問題最為合適。我們有大約三千臺Windows2003IIS6伺服器。這些程式碼執行在.NET2.0上,少部分是.NET3.5。不同的.NET的版本會造成各種麻煩問題,不過前端還是執行了.NET2.03.5。我們使用經過調節的SQLServer作為後端儲存。不過資料庫查詢的效能不足以應對站點對伸縮性的要求,因此我們開發了一個自定義的快取元件。這是個簡單的物件儲存部件,透過自定義的socket層進行通訊,全部儲存在64.NET2.0機器中的非託管記憶體中。因為我們最早遇到的問題之一便是.NET的垃圾收集器。

 

就算在64位平臺上,回收和壓縮數以億計的物件還是會造成較為明顯的延遲。所以我們面向伸縮性的問題之一便是必須自己編寫非託管的記憶體儲存。我們在儲存的前端使用.NET進行通訊,並與這一儲存層進行互動——我們稱之為快取層,這大大降低了資料庫的壓力。現在我們的資料庫從SQL2000升級至64SQL2005,這樣記憶體中可以存放更多的資料,這帶來了很大的效能提升。起初我們使用Windows2000中的CodeFusion5以及少量的資料庫。我們最早在資料庫伸縮性方面做的努力是進行了縱向劃分——或橫向劃分,我不知道你們把這叫做什麼方向——把每100萬個使用者放在不同的資料庫中。

 

這麼做提高了伸縮性,也讓我們能夠輕鬆地新增硬體,並對錯誤進行隔離。如果一個資料庫當機了,只有一小部分使用者會在我們處理這個問題之前得到錯誤資訊或正在維護的訊息。我們在Linux上構建了一個自定義的分散式檔案系統,用於存放使用者上傳的媒體內容,並作負載均衡。所有的影片或mp3等內容都放在這個自定義的DFS層上,實現了跨資料中心的冗餘,並透過HTTP直接從磁碟中獲取資料。

->你們在擴大網站規模時遇到了哪些挑戰?你提到,一開始你們使用了CodeFusion伺服器,不過現在使用了數以千計的IIS伺服器。你們是怎麼進行切換呢?你們擴大網站規模時只是透過增加伺服器數量嗎?

許多伺服器用來構建中心快取了,這可以大大降低資料庫伺服器的壓力。還有,如果你使用大量後端資料庫,就可能會遇到一個問題:如果其中一個資料庫伺服器當機了,那麼它會很快拒絕來自Web伺服器的請求,問題不大。不過,假如只是這個後端伺服器變慢了,試想某臺Web伺服器正在為大量不同的使用者提供服務,很可能其中一個緩慢的請求就會阻塞在這個壞的資料庫上。

 

不過此時其它請求依舊工作正常,不過遲早就會有另一個請求阻塞在壞資料庫上。可能過了十幾秒鐘之後Web伺服器上所有的執行緒就被這個資料庫阻塞了。所以我到那裡之後第一個架構的東西便是錯誤隔離系統,它執行在每臺Web伺服器上說:我只允許同時向同一範圍的伺服器發起x個請求。這避免了單個壞伺服器讓整個站點停止響應。原本我們會在擴充套件的同時可能會遇到越來越糟糕的情況,因為新增了更多可能會造成單點失敗的地方,整個站點停止響應的可能性也提高了。現在我們在IIS上部署了錯誤隔離模組,這樣增加了網站的正常執行時間。再加上快取層的功效,正常執行時間進一步增加了。

->聽上去你們做得很多事情都是在現有工具的基礎上構建擴充套件,那麼在微軟平臺上這麼做的感覺如何?

感覺非常好。我們使用微軟的Powershell。它早先的程式碼名(codename)是Monad,提到這個名稱的原因是我們從Monadbeta3就開始在生產環境中使用它了。它出現的正是時候,因為那段時間我們幾乎已經把所有推薦的Windows管理技術,例如VBScript、命令檔案等,都用到極限了。

 

那些東西在本機上工作的很好,如果你想要看另一臺機器上的登錄檔配置也不錯。不過如果要在數千臺伺服器執行命令的話,你就會遇到瓶頸。首先你只能每次訪問一臺伺服器,其次,如果遇到了一臺當機的伺服器,那麼整個工作就停止了。為了解決這個問題,我自己寫了一個簡單的遠端服務層,於是問題就又變成了我怎麼樣才能把它做的通用呢?我們希望可以輕鬆地對一系列的伺服器進行操作,比如執行一條命令,獲得一些結果,進行處理,然後可能執行另外一條命令——也就是說,這些操作形成了一個管道。

 

就在這時候PowerShell出現了,幫了很大的忙。PowerShell完全用.NET編寫,它在同一個程式裡執行所有的命令,這個好處在於命令A可以輸出各種東西,而不僅僅是字串,並讓命令B可以接著進行處理。它們之間可以順著管道傳遞任意的.NET物件,這樣就形成了一種非常強大的程式設計模型,讓那些只願意坐下來寫一點點命令的管理員們也樂於使用。於是我們就決定使用那些命令,例如我對MySpace“VIP”,意思執行特定功能的一組虛擬IP。如果我說“ProfileVIP”,意思就是指執行profiles.myspace.com的所有幾百臺伺服器,然後可以對它們統一進行處理。於是我們構造了一個叫做“GetVIP”的命令。

 

我們使用RunAgent命令的管道,可以並行地在遠端機器上執行任何命令,並把任何物件放進管道里。例如你可以用PowerShell的語法來描述告訴我這個東西是true還是false,某個檔案是不是存在,然後把結果傳遞到另一個管道中,不斷傳遞,這樣就可以快速地處理一些特定的管理任務。人們在寫指令碼的時候就不需要擔心網路是否失敗,也不用擔心多執行緒執行的狀況,因為我已經把這些問題處理掉了。我抽象了網路連線,抽象了並行特性,這樣可以把一些本來要花30分鐘甚至1小時的工作用大約5秒鐘就完成了,更可靠,可容易控制,更容易進行帳戶管理或日誌記錄。

->真厲害。我想你之前一定也聽到過這樣的問題,為什麼你們會選擇使用微軟的技術而不是其他一些常見的選擇呢?

嗯,在我到來之前其實就已經做出這個決定了,我剛到的時候系統執行在CodeFusion平臺上,有大約兩千萬使用者。我們有非常非常優秀的.NET開發人員,不過我不確定我們到底是專門找了.NET方面的人才,還是找了最好的開發人員,然後他們正好談到“.NET是個不錯的東西,我們就試試看吧。不過我認為,事實上我們很早就已經使用微軟平臺了,因此延續使用.NET是一件很自然的事情。我也不是一個搞Java的人,我的背景和微軟技術比較接近,微軟也給了我們不少幫助,讓我們在使用.NET這個相對較新的技術時度過了一個個難關,所以它給我的感覺還是相當不錯的。

->剛才你提到,你們混合使用了.NET2.0.NET3.5?它們配合的怎麼樣?有沒有計劃完全遷移到3.5上?

微軟現在在版本號的使用上有些瘋狂。我早先看了看他們的路線圖,其實3.5不過是在2.0的基礎上增加了一點擴充套件。所以你安裝了3.5之後自然就有了2.0的執行基礎。這種做法有點奇怪,不過我覺得3.5中的有些東西似乎還不錯,例如WindowsCommunicationFoundation提供了很方便的webservice功能,還包括了事務控制等特性,讓我們放棄了老舊的remotingwebservice程式設計模型。我們對WCF還沒有使用太久,不過看上去這些東西很令人興奮,它可以讓我們擺脫不少已經存在多年的負擔,以前我們不得不編寫自己的網路通訊類庫,只是因為remotingwebservice功能上存在一些小毛病。

->所以說,整個網站是建立在2.03.5之上的,你們使用的工具基於PowerShell。不過還有一點,你們整個系統裡有沒有配合使用的除錯工具呢?

這些工具裡我最喜歡的是一個叫做“Profiler”的工具。它使用C++編寫,基於微軟CLR偵測(profiling)介面,所以我們只要說“OK,我們的堆疊轉儲介面可以展示一些實時的資訊,比如當前各個部件都在做什麼事情,然後偵測介面就能說好吧,我會每10秒對這個執行緒進行一次檢查,我會從頭至尾監測一遍,我會告訴你每個呼叫花費了多少時間,告訴你每個異常的資訊,每次記憶體分配,鎖的競爭狀況,還有各種依靠偵錯程式檢視靜態狀態等做法獲取不到的資訊

 

這個Profiler的作用不光是在錯誤的情況下告訴我們發生了什麼,還可以在正常狀況下告訴我們那些請求對系統產生了什麼樣的影響。我們的系統中有大量不同的人寫的各式各樣的模組,所以對我這樣的人來說,就算已經對系統有所瞭解了,檢視那些跟蹤記錄有時候也會有新發現,比如我不知道我們居然做了這些事情。它可能是我們開發的技術最複雜的工具,這也是僅有的幾個不使用.NET開發的工具之一,這是因為你無法編寫.NET程式碼來監測.NET程式碼。這裡我們用了很多C++,有意思的是它利用了微軟研究院的Detours類庫,在技術上類似於他們用來偷偷摸摸為核心打補丁的方法:把現有程式碼導向別處,再呼叫回來,這樣程式並不知道自己已經被打上了補丁了。我們也用這種方式來獲得一些微軟的介面無法提供但有時候特別有用的一些資訊。

->你提到了C++,我記得你之前也談到過VBVBScript

大約兩年前我們使用VBScript。現在我們使用C#作為.NET開發語言。

->MySpace內部使用什麼語言呢?

我必須提到CLR本身基本上完全是由C#編寫的。我們內部也有一些先驅在嘗試一些諸如F#之類的東西。F#來自微軟研究院,看上去是個相當不錯的東西。我在不少工具裡嵌入了IronPython指令碼,因為我覺得就配置工作而言,它可以帶來更多控制能力。與鉤選幾百個選擇框相比,我現在只要幾句IronPython指令碼就能完成工作了。就總體來說,我們用C#做前臺和後臺開發,在各種必要的時候就會用到IronPythonPowerShell

->你們打算遷移到LINQ等各種.NET3.5新特性上嗎?

事實上LINQ給我的感覺可謂一天比一天深刻。我找不到任何理由不讓所有的伺服器升級,或者不讓開發人員使用它。LINQ看上去是個非常巧妙的技術,對於像我這種喜歡寫SQL查詢的人來說,可以用LINQ來處理XML,各種物件或記憶體中的資料,這種感覺實在是太酷了。可能有一天我們還可以使用自定義的Provider,誰知道呢?真是個不錯的東西,我希望很快就能在伺服器上看到LINQ的使用。

->對於最近釋出的MySpace開發者工具,你們有沒有打算讓開發人員可以使用一些不同的語言,例如C#?還是讓他們繼續基於JavaScriptVBScript這樣的指令碼語言進行開發?

其實我還沒有確定未來的打算。我知道剛釋出的開發者平臺是網站上的小部件(widget),可惜目前只支援JavaScript。也許您自己的富客戶端應用程式可以呼叫系統中完整的API,不過我實在無法確定這方面內容。

->對於MySpace這樣的大型網站來說,如果你遇到了問題,例如伺服器的負載到達了峰值,有沒有辦法可以建立一個補丁讓問題直接消失,還是隻能一點一點地改變,把問題分成幾個部分依次解決?

這個問題很好,我覺得要從兩方面來看這個問題。一是發現問題,二是解決問題。很多時候我們會發現“OK,站點的請求排隊了,我們該怎麼辦?我們其實不知道為什麼會發生這個情況,然後只是增加了幾臺伺服器。好,似乎問題有所改善,不過其實你並不知道這時是否應該增加伺服器,有可能只是後臺的資料庫剛好在進行備份。這不僅在於你不知道哪裡出現了錯誤,還有目前的做法可能在今後就不起作用了。所以一開始的困難在於,我們要如何開始識別這些問題,我們該如何讓前端網路操作中心(NOCNetworkOperationCenter)的人有能力指出這些問題。一旦這個困難解決了,那麼他們就可以比較容易確定該向誰彙報問題。

 

當然,有可能這的確是一個程式碼上的問題,我們努力希望讓中間層或後端的程式碼與前臺相容。如果我們釋出了一個東西,結果在QA時正常,測試時正常,但是釋出到網站之後卻有問題了但又不清楚是什麼原因,那麼最簡單的方法是回滾這次釋出或是禁用這個功能。一般來說,使用了正確的工具包之後,很少會出現找不出問題所在的情況。一開始我們的工具包比現在要小得多,不過如果每天都會發現類似的問題,那麼我們會說好,那麼我們用偵錯程式檢查一下,第二天說我再用偵錯程式看看這個問題,而第三天:算了,我要自己寫一個工具,現在的那些派不上用場。於是我們的工具包越來越完整,這樣快速發現和診斷問題的能力也就提高了。

->整個排錯的過程是什麼樣的呢?系統是如何適應伸縮要求,這一點上理論和產品上有沒有什麼區別呢?它又是如何影響系統架構的呢?

嗯,目前系統架構模型主要分為三層:前端,快取層和資料庫。所以要大幅度改進其伸縮性會是件困難重重的事情。我們一開始會說我們現在的這條資料庫查詢不太好,那麼我們試試看簡單的修復一下,把它放到快取中去。好吧,這沒啥效果,那麼我們可能要建立另一套系統了。我們就開始琢磨這個問題,我們有不少這樣的系統,如果效能出現問題了那麼我們可以對它們分別進行最佳化,比如把這部分移出資料庫,放到磁碟上,或者就放在記憶體中。如果某個地方出現了問題,那麼我們會開發一個新的系統。這在MySpace中並不多見,因為我們在一開始在水平分割上的考慮十分有效。不過當你打算獲得更多9【譯註:即99.99……%】的可用時間時,就會在決策上有很大的改變。

->這可能是個有2-3年曆史的老問題了,不過在提及“.NET無法伸縮的問題時,你會怎麼答覆呢?

我覺得不存在這方面問題,關鍵在於你有沒有使用正確工具,是否有這方面的專家。事實上我覺得現在.NET已經是一個非常成熟的平臺了。顯然Java在這方面領先於.NET,不過我想我們還是網際網路上最大的.NET站點。我不知道你會把我們的可用時間和效能與同樣規模的Java站點進行什麼樣的比較,我們遇到的各種問題都不是.NET平臺本身造成的。可能是我們自己的bug,可能是硬體問題,但是我沒有真正遇到過.NET的問題,除了在垃圾收集方面我可能會說這的確很難進行伸縮

 

不過.NET上最好的地方莫過於它的可擴充套件性了,所以如果垃圾收集器在你16GB的機器上進行記憶體管理時表現不好,那麼你可以使用BerkeleyDB或你自己的非託管儲存進行替換。要享受.NET的優勢也不必把自己完全侷限在.NET中。我想說.NET有良好的伸縮性,而且我們的規模也會越來越大。你不妨過幾年再來問我這個問題,看看我會怎麼說。

->你們在伺服器或伸縮性方面有沒有使用其他的微軟企業產品?

應該說,有新東西出來的時候我們就會試試看。例如EnterpriseApplicationBlockRemotingWebService我們都嘗試過。如果你真想做一個大規模的應用程式,那麼這就是我的建議:一般來說,我們最後會使用自己的實現,因為我們不需要如此通用的解決方案,我們真正需要的是效能。我想說的是,我們嘗試了某個東西之後就從中學到些東西,然後可能就會把其中有價值的地方給剝離出來,再為了達到我們的效能或伸縮性需求重新寫一個。我不覺得微軟會在我們這種規模的應用程式中進行測試,所以好像是我們在為他們測試一樣。所以,如果有些東西可以在幾十臺服務規模的程式中工作正常,但是無法滿足MySpace的伸縮性要求,我覺得這是一件稀鬆平常的事情。

->你能否給出一個例子,關於對.NET或微軟告訴你應該做的東西,卻反其道而行之?

我覺得我寫的Profiler算是一個吧。如果他們不會發現的話,我會使用很多肯定違反伺服器擔保條例的東西,例如因為效能為CLR程式碼打補丁。我們看了很多C++執行時的程式碼,也一直用Reflector來檢視內部情況,可能有時候還會在產品程式碼中用到反編譯來修補一些我們覺得微軟做的不好的東西。不過我們儘可能避免這種做法,所以我舉不出一個真正的例子來說明我們在什麼地方反其道而行。不過每次遇到這些小問題時,我們會說不如稍微修改一下,希望能夠有用,而不是好吧,我們重新用一個新的技術

->你能多談一寫快取層的東西嗎?我對你處理一些常見的快取問題的方法很感興趣,例如更新之類的事情。

我們正好在處理這方面的問題。目前,快取層既不是writethrough也不是readthrough的。基本上web伺服器做的事情會分兩步走。首先檢查快取,如果沒有東西,那麼web伺服器會從資料庫裡取出物件並序列化,傳送給使用者頁面,然後非同步地提交給快取,然後下一次再重複這個過程。我相信在某些時候我們會使用一個更加傳統的三層模型,這樣web伺服器不會直接連線資料庫,不過目前我們仍然基於簡單的兩層:web伺服器和資料庫,而快取層只是簡單的附屬物。當以後規模越來越大時,我們就會著手把訪問轉移到快取中,最終會讓web伺服器連線快取伺服器,而不是資料庫。

 

不過目前看來,物件儲存工作得相當不錯,我們也在這方面思考了很多。它只是用來儲存物件,它並不知道儲存了什麼或者那些東西從哪裡來,這對效能可能有些好處,我不確定。不過從幾年前我們需要快取的時候,就把它設計成可以輕鬆增加的服務。我們現在有400臺執行飛快的伺服器,如果有東西變慢了,那麼我們就會進行升級。沒什麼特別的。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-609635/,如需轉載,請註明出處,否則將追究法律責任。

相關文章