Facebook性能大提升的祕密:HipHop

HipHop

Facebook神祕的PHP項目HipHop for PHP終於揭開面紗。這個項目由一個PHP到C++的轉換程序,一個重新實現的PHP運行庫,和許多常用PHP擴展的重寫版本構成,目的是旨在加速和優化 PHP。

Facebook 官方博客 (無法直接訪問)上項目負責人趙海平(北大1987屆遺傳與分子生物專業,普林斯頓計算機科學博士)的話說,HipHop項目對 Facebook影響巨大。它目前已經支撐了Facebook 90%的Web流量。由於HipHop,Facebook Web服務器上的CPU使用平均減少了50%,從而大大減少了服務器的需求。爲了讓這一改進也惠及社區,他們決定將之開源,希望能夠進一步幫助提高更多大 型複雜PHP網站的可伸縮性。

PHP和Facebook的問題

衆所周知,Facebook的前端主要是用PHP寫的。趙海平說,過去六年Facebook從PHP語言的進展上獲益良多。PHP非常簡單,易學易 用,好讀好調試,因此新工程師成長很快,有利地促進了Facebook的更快的創新。

PHP是一種腳本語言,其好處是編程效率高,能夠支持產品的快速迭代。但是與傳統的編譯語言相比,腳本語言的CPU和內存使用效率不好。隨着 Ajax技術的廣泛採用,加上SNS對動態要求較高,這些缺點更顯得突出。對於每月超過4000億次PV的Facebook來說,如何實現擴展,尤其具有 挑戰性。

常見的辦法是直接用C++重寫PHP應用中比較複雜的部分,作爲PHP擴展。實際上,PHP就轉變爲一種膠水語言,連接前端HTML和C++應用邏 輯。從技術角度講這也沒有問題,但是增加了技能需求,能夠在整個應用上工作的工程師數量就大大減少了。學習C++只是編寫PHP擴展的第一步,接下來還要 理解Zend API。由於Facebook的工程團隊較小,每個工程師要支持100萬以上的用戶。有些代碼不是團隊裏每個人都能看懂,這對於Facebook是無法接 受的。

Facebook網站本身的可伸縮性更具挑戰性,因爲幾乎每次頁面瀏覽都是有個性化體驗的登錄用戶發起。瀏覽主頁 時,系統需要查詢所有朋友、朋友最重要的狀態更新、 根據隱私設置篩選結果,然後還要顯示評論、照片等等動態,這一切都需要在一秒內完 成。

自2007年以來,Facebook曾寫過幾種不同辦法解決這些問題。其中包括用另 一種語言重寫Facebook,但是由於開發的複雜性和速度等原因,未能實現。他們還重寫了PHP的核心部分Zend引擎,並提交給了PHP項目,但最終 還是沒有獲得所需的性能。最後,他們選擇了HipHop,終於得償所願。

有了HipHop,工程師可以編寫代碼,用PHP編寫組合最後頁面的邏輯,並能夠繼續快速迭代,同時後端服務使用C++, Erlang, Java, Py thon編寫,提供新聞提要、搜索、聊天和其他核心功能。

HipHop開發故事

趙海平透露,項目最初是來自幾年前Facebook公司一次Hackathon活動(員工在一個晚上自由發揮,實驗新的想法),他手工將PHP轉換 爲C++代碼,雖然語法上很類似,但是無論是CPU還是內存使用,轉換後的C++代碼都大大優於PHP。於是他想,如果構建一個系統,編程實現轉換,會怎 麼樣呢?

在此之前,已經有了不少改善PHP性能的方法。Zend引擎在運行時轉換PHP源代碼爲運行在Zend虛擬機上的opcode。開源項目APC和 eAccelerator將輸出緩存,爲大多數PHP網站所使用。此外,還有Zend Server這樣的商業產品,通過opcode優化和緩存,提高PHP速度。趙海平選擇了另一條道路,將PHP直接轉爲C++,然後再變成本地機器碼。當 然,有許多開源項目也是同樣的思路,Roadsend和phc編譯爲C,Quercus編譯爲Java,而Phalanger編譯爲.NET。

Hackathon之後8個月,趙海平拿出了原型,足以說明這條路可以走通,編譯後的代碼的確更快。不久,Iain Proctor和Minghui Yang加入進來。接下來又開發了10個月,在生產服務器上測試了6個月。然後正式上線部署,6個月之後,Facebook 90%以上的Web流量都使用了HipHop。

按趙海平的說法,憑藉HipHop,Facebook Web服務器上的CPU使用平均減少了50%,從而大大減少了服務器的需求。項目對Facebook影響巨大。爲了讓這一改進也惠及社區,他們決定將之開 源,希望能夠進一步幫助提高更多大型複雜PHP網站的可伸縮性。

HipHop的原理

HipHop將PHP代碼轉換爲高度優化的C++代碼,然後再用g++編譯器編譯。它可以保持語義等效地執行源代碼,但爲了提高性能,犧牲了一些很 少用到的特性,比如eval()。

HipHop開發中的主要困難在於,在PHP和C++這兩種很不一樣的語言之間怎麼實現轉換。雖然PHP也可以寫一些很巧妙的動態特性,但是大多數 PHP代碼還是非常簡單的。if (...) {...} else {..} 比foo($x) { include $x; } 肯定更常見。這爲性能提高提供了機會。HipHop生成的代碼儘可能地使用函數和變量的靜態綁定。同時,還使用類型推演來選出變量最可能對應的某個類型, 從而節省內存。

轉換過程分三步:

1. 靜態分析。收集聲明關係和依賴關係等信息。

2. 類型推演。選擇最合適的類型,是C++的標量?還是String, Array, classes, Object或者Variant。

3. 代碼生成。大部分直接將PHP語句和表達式對應爲C++的語句和表達式。

在開發過程中,還有一個副產品:HPHPi,是一個實驗性的解釋器。通過它,不編譯PHP源代碼也可以運行。它已經用於HipHop自身的調試中。

HipHop在保持了PHP優點的同時,也兼得了C++的性能優勢。項目總共有30萬行代碼,5000多個單元測試。所有這些都將以PHP開源許可 證形式發佈到GitHub。

更多信息,可以申請加入HipHop的郵件列表:

http://groups.google.com/group/hiphop-php-dev

發佈了31 篇原創文章 · 獲贊 11 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章