原文:陳皓
本文主要參考了Phil Whelan的這篇文章《Quora’s Technology Examined》。關於Quora是個什麼網站我就不多說了,國內對他的C2C網站叫“知乎”。呵呵。我們還是來看看Quora的技術吧。
Search-Box
Quora只能搜尋問題,主題標籤,使用者名稱,和主題標題。沒有全文搜尋,所以,你無法搜尋問題和答案的內容。而搜尋中使用字首搜尋方式,比如你 輸入mi,則Microsoft會馬上出來。其搜尋還會有一些非常簡單的模糊匹配的演算法。另外,如果有重複的問題,其中一個問題會自動跳轉到另一個問題, 但是在搜尋中還是會出現。搜尋中沒有拼寫檢查。
一開始,他們使用的是一個開源的搜尋伺服器,叫Sphinx。其支援上述的那些功能。現在他們不用這個技術了,因為受到了一些限制。他們做了一個比較新的解決方案,這個演算法由Python實現。
參看:What libraries does Quora use for search?
實時查詢
Quora的查詢是非常高速的,其查詢請求是通過AJAX的GET請求傳送的,結果返回用的是JSON資料格式,但他們解析JSON是在伺服器 端,而不是通過瀏覽器的JavaScript。這麼做的原因可能是他們想高亮搜尋關鍵詞,似乎使用Client端的JavaScript非常不好做。
Quora的即時搜尋好像比較暴力,如果你輸入Microsoft(一共9個字元),你會看到其會像後端傳送9次查詢——每按一個鍵一次,無論你敲這個單詞的速底有多快,這個事情交給伺服器端來控制,所以,這樣做不會讓增加伺服器端的負載。
Quora的搜尋使用HTTP長連線,當你開始敲查詢的時候,連線就建立了,這個連線會持續在那裡,你下次搜尋的時候會繼續使用這個連線,除非你60秒沒有動作了。
參看:Is Quora going to implement full-text search?
Webnode2 和 LiveNode
Webnode2 和 LiveNode 是 Quora 內部的系統,其用來管理內容。Webnode2 生成 HTML, CSS 和 JavaScript 並且和 LiveNode 緊緊地耦合在一起,Webnode2主要是用來管理內容在網頁上顯示的。Charlie Cheever 說,如果他可以從新開始,他 第一件事要做的就是重寫整個LiveNode.
Quora的工程師看上對他們搞的這些東西非常的滿意,並且 他們也在努力地找到這些東西的弱點。 有一個有意思的關於LiveNode的問題是,如果A和B同時正在看相當的一個問題,如果使用者A的一些互動動作為影響B的。例如,如果A頂了一下某個答 案,那麼這個答案可能會往上移動。這樣的一個顯示變化會通過AJAX更新B的瀏覽器。如果B此時展開了評論,可能會受到影響。
LiveNode 由這些東西寫成:Python, C++, JavaScript. jQuery, Cython也用到了。
因為Quora 想要對他們的LiveNode開源 並準備把他們的程式碼分開,做這個事可能需要太多的工作和時間。
Charlie Cheever 指出 WebNode2 和 有一個叫做“free and easywebsite builder”的 Webnode 的webnode.com 沒有任何的關係。
Amazon Web Service
Quora全部host在AWS的EC2和S3上,這對於這些剛剛起步的快速發展的公司非常關鍵,因為你可以省去了很多硬體和維護的成本。(建一個資料中心並不是所有公司都能幹的事)。Quora的作業系統使用Ubuntu Linux,這是非常容易部署和管理。
其靜態頁使用了Amazon的CDN的 Cloudfront 服務分發,CloudFront用於所有的靜態圖片, CSS 和JavaScript。圖片先傳到 EC2 伺服器,使用 Pyhon S3 API 處理後後傳到 S3。
HAProxy Load-Balancing
HAProxy 作為前端負載均衡伺服器,反向代理伺服器是 Nginx,Nginx後面則是 Pylons (Pylons + Paste),承擔動態 Web 請求。
Pylons,是一個輕量級的Web框架,通常都是在Nginx後面使用。選用Pylons就像你在春節先餃子當主食一樣。他們把Pylons中的template和ORM取走而使用自己的技術(由Python寫成),這個地方就是 LiveNode 和 WebNode2的地方。
Python
從 Faceboook 出來的 Charlie 和 Adam 選用了Python而不是PHP。正如Adam指出的——“Facebook is stuck on that for legacy reasons, not because it is the best choice right now” (Facebook使用PHP並不是因為其好,而是因為歷史原因的問題),當然他們也不會使用C#,因為那樣一來就會引入一堆微軟的東西。當然,也不會是 Java,因為Python要比Java更容易寫出程式碼,Scala太年輕了,還需要考驗。Ruby看上來很像Python,但是他們對Ruby沒有過多 的經驗。最終還是Python勝出。當然,他們知道Python的弱點是效能和速度,所以,他們在需要速度和效能的地方使用了C/C++。使用的 Python的版本是2.6。
使用Python的另一個原因是Python的資料結構和JSON可以很好的對映起來。程式碼易讀性很高。而且有很多的庫,偵錯程式和過載器。Quora的B/S結構幾乎完全通過JSON進行資料互動。
他們沒有使用IDE,他們使用得最多的是Emacs,一看就知道這是一個個人的選擇,隨著他們開發團隊的擴大,這個事會得到改變的。
另外,他們提到了PyPy,一個讓 Python更快更靈活的專案。
Thrift
Thrift 用於後端伺服器間的通訊。Thrift 服務由 C++開發。Facebook同樣使用了這個技術。
參考:Why would you write a Thrift service in C++?
Tornado
Tornado Web 框架用於實時更新,其執行在Comet伺服器上,其用來處理大量的需要長時間poll和push更新的網路連線。
Long Polling (Comet)
Quora的網頁並不是簡單的顯示,每一個頁面都需要更新,或是建立問題,答案和評論。所以,他們使用了Long Polling而不是傳統的Polling,傳統的Polling需要瀏覽器一端不停地重複地向伺服器詢問——“有更新嗎?”,伺服器說沒有,於是過一會 瀏覽器再問,現在呢?伺服器說,還是沒有,瀏覽器過一會又問,現在呢?伺服器說,還沒好。這樣一來,就好像讓我們的客戶端放到了駕駛室裡,這顯然是有問題 的,因為只有伺服器知道什麼時候會有更新。而且瀏覽器這麼幹,很快會讓伺服器的負載加上去。
Long polling 也就是我們熟知的 Comet, 其讓伺服器來控制這些事,讓客服端等在那裡聽伺服器的響應。在client和server的會話對於兩者是是相同的,而不是client需要等著然後向服 務器查詢。伺服器端可以把一個連線開啟很長時間(比如:60秒),在這段時間裡,伺服器會檢視是否有相應的東西需要更新,如果有的話,就發給瀏覽器。如果 沒有的話,就等下一次的client詢問。可見,這種伺服器等一會再響應的方法可以讓瀏覽器少發幾次查詢。
對於long-polling 的最好的地方是,可以降低瀏覽器和客戶端間來來回回的次數。讓伺服器端來控制時間,所以,內容更新可能會只是幾個毫秒,或是幾十秒。伺服器端也可以積攢一堆更新後,一次發給瀏覽器。這樣做會更有效率。
但是,這個方法的黑暗面是——這會讓伺服器端出現大量的TCP連結,想一想,Quora也是百萬級使用者的應用了,只需要10%的線上使用者,你就 需要一個可以處理10萬併發量的架構。注意,如果一個使用者在其瀏覽器裡開啟了多個Quora網頁的話,那麼,這個連結器會是非常致命的。
當然,好的訊息是已經有一些技術專門為Long Polling設計,這些技術可以讓你在那些等待的連線中只會消耗非常非常少的記憶體(因為那些等待連線並不需要所有的資源)。例如:Nginx是一個單線 程的事件驅動的小型伺服器,每一個連結只花非常小的記憶體。每一個Nginx的程式只會在一個時候處理一個連線。這意味著其很容易擴充套件成一個可以處理成千上 的併發量的服務架構。
MySQL
就像Adam D’Angelo 的老東家facebook一樣,Quora重度使用MySQL。對於,把資料庫裡的資料分割槽是最需要做的事。他們的行事原則是,儘可能的把資料放在一臺機 器上,使用hash主鍵把大規模的資料存放到多個資料庫中。堅決不用表連線。Adam參考了FriendFeed的一篇文章How FriendFeed uses MySQL to store schema-less data,並說你不應該在你的社群還沒有100萬使用者的時候使用NoSQL 資料庫。
並不只是Quora和FriendFeed使用MySQL;Google, Twitter, Facebook都在使用MySQL.
Memcached
Memcached 用於 MySQL的前端快取。
Git
JavaScript Placement
如果你看一下Quora的網頁原始碼,你會看到其JavaScript總是在頁面的最後。 Charlie Cheever建議這會讓你的頁面顯得載入得很快,因為其先顯示內容,然後在載入Javascript。
Charlie Cheever 遵從“14 Rules for Faster-Loading Web Sites”
Steve Souders, High Performance Web Sites 和 Even Faster Web Sites的作者,其列了一些 rules讓你網頁更快的原則。 Charlie Cheever 的 Quora 創始人提到這些過,這應該也是Quora的速度的原因。[INDENT] “One resource we used as a guide is Steve Souders’ list of rules for high performance websites:http://stevesouders.com/hpws/rules.php”
– Charlie Cheever, Quora
Steve Souders的14條規則是——
- Make Fewer HTTP Requests
- Use a Content Delivery Network
- Add an Expires Header
- Gzip Components
- Put Stylesheets at the Top
- Put Scripts at the Bottom
- Avoid CSS Expressions
- Make JavaScript and CSS External
- Reduce DNS Lookups
- Minify JavaScript
- Avoid Redirects
- Remove Duplicate Scripts
- Configure ETags
- Make AJAX Cacheable