淺談Facebook的伺服器架構
大體層次劃分
Facebook的架構可以從不同角度來換分層次。
一種是:
一邊是PHP整的經典的LAMP stack;另外一邊是非PHP整的各種service。
Facebook的頁面從剛創立的時候扎克伯格寫的,到現在,都用PHP開發。後端有用各種語言開發的service。它們之間用跨語言的thrift RPC通訊(Scribe也是建立在Thrift之上)。
另外一個角度劃分的層次是:
前面是負載局衡器(沒說是用硬體的還是軟體的);負責分配前端的Web伺服器,Web伺服器是用PHP來聚合資料;最後面是 Services,Memcached和資料庫。
有意思的是對後面三種的定性:
Services – 快速,複雜; 自己開發的業務程序,來實現複雜的業務邏輯,速度快。
Memchached – 快速,簡單;Memchached做簡單的key-value快取,服務應用快速的讀請求。
資料庫– 緩慢,持久。資料庫做持久儲存,磁碟IO自然慢,不過有memcached做快取沒關係。
NewsFeed的架構
寫:
Bob更新狀態,Web伺服器上的PHP程式除了將內容寫到MySQL資料庫之外,也將該行為動態的ID通過Scribe發到一個Leaf Server上(根據Bob的使用者ID選的Leaf Server)。
讀:
另一個人Alice開啟Facebook,載入主頁,PHP程式向Aggregator伺服器查詢(Thrift呼叫),Aggregator從若干個Leaf Server裡頭讀出Alice的朋友的所有行為動態/action的前四十個,aggregator做聚合和一定的排序,返回給PHP程式。
PHP程式獲得這些行為動態的ID之後,從Memcached中讀出這些ID對應的內容,如Memcached沒有,則從MySQL資料庫中讀,匯聚後生成HTML返回給瀏覽器。
Chat的架構
頁面請求,仍由WEB伺服器處理(PHP)處理,當然也依賴web tier之後的各種Service。比如檢視訊息歷史啊,線上使用者列表啊,傳送聊天訊息啊。
接收聊天訊息,則沒通過PHP伺服器,而是專用的用Erlang寫的Channel伺服器來處理,通過long-polling來接收聊天訊息。Channel伺服器是Chat服務的核心部件。傳送的訊息通過web tier發到Channel伺服器。
後方有用C++寫的chatlogger伺服器來做歷史記錄的讀寫。
同樣也用C++寫了presence伺服器來從channel伺服器彙集線上狀態。
系統的簡化結構如下圖所示:
Web tier, chatlogger, presence, channel 都是多個伺服器組成的叢集。
Channel伺服器有根據User ID做分割槽,每個分割槽由一個高可用的Channel叢集服務。
Webtier, chatlogger, presence,在公開的文章和PPT中並沒說這些叢集具體怎麼做分佈和冗餘備份的。
Facebook優化的細節技術:
Memcached
Memcached是一款相當有名的軟體。它是分散式記憶體快取系統。Facebook(還有大量的網站)用它作為Web伺服器和MySQL伺服器之間的快取層。經過多年,Facebook已在Memcached和其相關軟體(比如,網路棧)上做了大量優化工作。
Facebook執行著成千上萬的Memcached伺服器,藉以及時處理TB級的快取資料。可以這樣說,Facebook擁有全球最大的Memcached裝置。
HipHop for PHP
和執行在本地伺服器上程式碼相比,PHP的執行速度相對較慢。HipHop把PHP程式碼轉換成C++程式碼,提高編譯時的效能。因為Facebook很依賴PHP來處理資訊,有了HipHop,Facebook在Web伺服器方面更是如虎添翼。
HipHop誕生過程:在Facebook,一小組工程師(最初是3位)用了18個月研發而成。
Haystack
Haystack是Facebook高效能的圖片儲存/檢索系統。(嚴格來說,Haystack是一物件儲存,所以它不一定要儲存圖 片。)Haystack的工作量超大。Facebook上有超過2百億張圖片,每張圖片以四種不同解析度儲存,所以,Facebook有超過8百億張圖片。
Haystack的作用不單是處理大量的圖片,它的效能才是亮點。我們在前面已提到,Facebook每秒大概處理120萬張圖片,這個資料並不包括其CDN處理的圖片數。這可是個驚人的資料!!!
BigPipe
BigPipe是Facebook開發的動態網頁處理系統。為了達到最優,Facebook用它來處理每個網頁的分塊(也稱“Pagelets”)。
比如,聊天視窗是獨立檢索的,新聞源也是獨立檢索的。這些Pagelets是可以併發檢索,效能也隨之提高。如此,即使網站的某部分停用或崩潰後,使用者依然可以使用。
Cassandra
Cassandra是一個沒有單點故障的分散式儲存系統。它是前NoSQL運動的成員之一,現已開源(已加入Apache工程)。Facebook用它來做郵箱搜尋。
除了Facebook之外,Cassandra也適用於很多其他服務,比如Digg。
Scribe
Scribe是個靈活多變的日誌系統,Facebook把它用於多種內部用途。Scribe用途:處理Facebook級別日誌,一旦有新的日誌分類生成,Scribe將自動處理。(Facebook有上百個日誌分類)。
Hadoop and Hive
Hadoop是款開源Map/Reduce框架,它可以輕鬆處理海量資料。Facebook用它來做資料分析。(前面就說到了,Facebook的資料量是超海量的。)Hive起源於Facebook,Hive可以使用SQL查詢,讓非程式設計師比較容易使用Hadoop。(注1: Hive是是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供完整的sql查詢功能,可以將sql語句轉換為 MapReduce任務進行執行。)
Thrift
Facebook在其不同的服務中,使用了不同的語言。比如: PHP用在前端,Erlang用於聊天系統,Java和C++用於其它地方,等等。Thrift是內部開發的跨語言的框架,把不同的語言繫結在一起,使之可以相互“交流”。這就讓Facebook的跨語言開發,變得比較輕鬆。
Facebook已把Thrift開源,Thrift支援的語言種類將更多。
Varnish
Varnish是一個HTTP加速器,擔當負載均衡角色,同時也用於快速處理快取內容。
Facebook用Varnish處理圖片和使用者照片,每天都要處理十億級的請求。和Facebook其他的應用應用一樣,Varnish也是開源的。
Facebook可以平穩執行,還得利於其他方面.雖然上面已經提到了一些構成Facebook系統的軟體,但是處理如此龐大的系統,本身就是一項複雜的任務。所以,下面還將列出使Facebook能平穩執行的一些東西。
1、Web 前端是由 PHP 寫的。Facebook 的 HipHop會把PHP轉成 C++ 並用 g++編譯,這樣就可以為模板和Web邏賀業務層提供高的效能。
2、業務邏輯以Service的形式存在,其使用Thrift。這些Service根據需求的不同由PHP,C++或Java實現。
3、用Java寫的Services沒有用到任何一個企業級的應用伺服器,但用到了Facebook自己的定製的應用伺服器。看上去好像是重新發明輪子,但是這些Services只被暴露給Thrift使用(絕大所數是這樣),Tomcat太重量級了,即使是Jetty也可能太過了點,其附加值對Facebook所需要的沒有意義。
除了語言層面的,還有很多架構,多數是開源架構,並且有很多是Facebook根據自己的業務需求而設計的架構並使之開源的。
4、持久化使用MySQL,Memcached,Hadoop'sHbase。Memcached是一個流行的快取,被用做MySQL快取。
5、離線處理使用Hadoop和Hive。
6、日誌,點選,訂閱傳輸這些資料使用Sribe,使用Scibe-HDFS被記錄和儲存在HDFS中,因此允許使用MapReduce進行擴充套件分析。
7、BigPipe是他們自己制定的技術,使用管道邏輯來加快頁面渲染。
8、VarnishCache用作Http代理,提升效能和效率。
9、10億級的海量圖片儲存和傳送,使用Haystack進行處理,這是一個由Facebook開發的專用的儲存解決方案,提高了優化水平並且可以追加寫。
10、Facebook訊息使用自己的架構,值得注意的是這個架構是一個共享的基礎架構,並且是動態叢集管理的,業務邏輯和持久化被封裝在稱為‘Cell’的東西中,每一個Cell都是使用者的一部分,新的Cell可以自由的新增。持久花技術使用HBash來完成。
11、Fackbook訊息的搜尋引擎構建在HBase的一個反向索引儲存上。
12、Fackbook搜尋引擎的實現細節目前我還不清楚。
13、輸入預搜尋使用自己定製的儲存器和檢索邏輯。