天天看點

twitter系統架構分析

twitter系統架構分析

twitter系統架構分析

(一)twitter的核心業務

twitter的核心業務,在于following和be followed:

(1)following-關注

進入個人首頁,會看到你follow的人發表的留言(不超過140個字),這是following的過程;

(2)followed-被關注

你釋出一條留言,follow你的人将看到這條資訊,這是be followed的過程;

(二)twitter的業務邏輯

twitter的業務邏輯也不複雜

following業務,查follow了哪些人,以及這些人發表的留言;

followed業務,前端js輪詢後端,看follow了的人有沒有新留言,有則更新(更新及時性取決于輪詢時間);

(三)三層架構(three-tier architecture)

網站的架構設計,傳統的做法是三層架構,所謂“傳統”不意味着“過時”,新潮的技術不成熟,傳統的路子更穩健。

(1)表示層(presentation tier):apache web server,主要任務是解析http協定,将請求分發給邏輯層;

(2)邏輯層(logic tier):mongrel rails server,利用rails現成的子產品,降低工作量;

(3)資料層(data tier):mysql;

資料層先來吧:

twitter的核心是(1)使用者;(2)消息;(3)使用者關系;

圍繞這幾個核心,其核心資料的schema設計:

(1)使用者表user

id, name, pass, status, …

(2)消息表msg

msgid, author_id, msg, time, …

(3)使用者關系表relation

id, following_ids, followed_ids

邏輯層:

當使用者釋出消息時,依次執行:

(1)存消息至msg表;

(2)查使用者relation表,找出其followed_ids;

(3)擷取followed_ids中使用者的狀态;

(4)線上的ids,将消息push進一個隊列queue;

(5)queue中的msg,更新ids的首頁;

這裡面要用到隊列,其實作方式有很多種,例如apache mina,twitter團隊自己實作了一個kestrel。

表示層:

表示層的主要職能有2個:

(1)http協定處理(http processor);

(2)分發器(dispatcher);

當然,通路twitter的不僅僅是浏覽器,可能還有手機,由于可能存在其他協定,故可能存在其他processor。

無論如何,架構架構清晰如下:

twitter系統架構分析

圖1:架構版本1

(四)cache=cash即緩存等于收入

cache的使用對大型網站架構至關重要,網站響應速度是影響使用者體驗最明顯的因素,而影響響應速度最大的敵人又是磁盤io。

twitter工程師認為,良好體驗的網站平均響應時間應該在500ms左右,理想的時間是200-300ms。

關于cache的使用,是twitter架構的一大看點,帶cache的架構清晰如下:

twitter系統架構分析

圖2:帶cache架構版本2

哪裡需要cache?IO越頻繁的地方,越需要cache。

資料庫是IO通路最頻繁處,三大核心表是否有必要放入記憶體中?

twitter的做法是,将表拆分,将其中通路最頻繁的字段裝入cache。

(1)vector cache and row cache即數組cache與行cache

vector cache:新發表消息的msgids,相關作者的ids,這些id的通路頻率很高,存放它們的cache稱為vector cache;

row cache:消息正文的行cache;

記憶體有限的情況下,優先vector cache,實際結果vector cache的命中率是99%,row cache為95%;

(2)fragment cache and page cache

通路twitter的使用者除了網頁(web通道),還有手機(API通道),而後者的比例占總流量的80%-90%。

mysql cache之外,cache的重心會在API通道上。

手機螢幕的主體,是一屏一屏的消息,不妨把整個頁面分割成若幹局部,每個局部對應一些/一條消息,這些就是fragment。

人氣高的作者,緩存其頁面的fragment,可以提高讀取其釋出消息效率,這就是fragment cache的使命。

人氣旺的作者,人們也會通路其首頁,這就是page cache的使命。

實際結果,fragment cache的命中率為95%,page cache為40%。

雖然page cache的命中率低,但由于是通路首頁,其占用的空間是很大的,為了防止兩種cache互相影響,這兩種cache需要部署在不同的實體機器上。

twitter的fragment cache和page cache都是使用的memcached。

(3)http accelerator

web通道的緩存問題也需要解決,分析之後,web通道的壓力主要來自搜尋。

面臨突發事件時,讀者們會搜尋相關資訊,而不會理會這些資訊的作者是不是自己follow的那些人。

為了降低搜尋壓力,可以将搜尋關鍵詞與搜尋内容cache起來,這裡,twitter的工程師使用了varnish。

有趣的是,varnish通常部署在web server外層,先通路varnish,其中沒有先關的内容,才通路web server;

twitter的工程師卻将varnish放在apache web server的内層,原因是他們認為varnish操作複雜,擔心varnish崩潰造成系統的癱瘓,故采用了這種保守型部署方式。

twitter沒有公開varnish的命中率,他們聲稱,使用了varnish之後,整站的負載下降了50%。

(五)抗洪需要隔離

twitter架構的另一大看點是其消息隊列:隔離使用者的操作,将流量高峰攤平。

餐廳客滿時,對于新來的顧客,雖然不能服務,但不是拒之門外,而是讓他們現在休息廳等待。

使用者通路twitter時,接待他的是apache web server,而apache不能接待無限多的使用者。

2009年1月20日,奧巴馬發表就職演說,twitter流量猛增,此時如何是好。

面對洪峰,如何保證網站不奔潰?迅速接納,但推遲服務。

apache收到請求,轉發給Mongrel,由Mongrel負責實際處理,apache則騰出手來,迎接下一位使用者。

但apache能夠接待的使用者數總是有限的,它的并發數受apache能夠容納的工作程序數量,這裡不細究apache内部原理,圖如下:

twitter系統架構分析

圖3:apache内部架構

(六)資料流與控制流

快速接納,推遲服務,隻是緩兵之計,目的是讓使用者不至于收到503(service unavailable)。

真正的抗洪能力,展現在蓄洪與洩洪兩個方面:

(1)twitter有龐大的memcached叢集,能大容量蓄洪;

(2)twitter自己的kestrel消息隊列,作為引流洩洪手段,傳遞控制指令(引流和管道);

洪峰到達時,twitter控制資料流,将資料及時疏散到多個機器,避免壓力集中,造成系統癱瘓。

下面舉例說明twitter内部流程,假設有兩個作者,通過浏覽器發消息,一個讀者也通過浏覽器閱讀他們的消息。

twitter系統架構分析

圖4:twitter流

(1)登陸apache web server,apache配置設定一個工作程序為其服務,登陸,查id,寫cookie等;

(2)上傳新寫的消息,把作者id,消息等轉發給Mongrel,apache等待Mongrel回複,以便更新作者首頁,将新寫的消息更新上去;

(3)Mongrel收到消息後,配置設定一個msgid,将其與捉着id等緩存到vector memcached上去;

同時,Mongrel讓vector memcached查找作者被哪些人follow,緩存如果沒有命中會去後端mysql查找,并入cache;

讀者ids會傳回給Mongrel,Mongrel把msgid與短信正文緩存至row memcached;

(4)Mongrel通知kestrel消息隊列伺服器,每個作者及讀者都有一個隊列(沒有則建立);

Mongrel将msgid放入讀者的隊列,以及作者本人的隊列;

(5)某一台Mongrel,它可能正在處理某一個id的隊列,就會往傳回該id使用者的首頁上添加上此條資訊;

(6)Mongrel将更新後作者的首頁給前端等待着的apache,apache則傳回浏覽器。

(七)洪峰與雲計算

不細說了,洪峰扛不住時,隻能加機器。

機器哪裡來?租雲計算平台公司的裝置。

當然,裝置隻需要在洪峰時租用,省錢呀(@58沈劍 疑問:twitter怎麼知道什麼時候是洪峰?)。

(八)push與pull的折衷

可以看到,Mongrel的工作流程:

(1)将相關ids放入vector memcached和row memecached就算消息釋出成功,而不負責mysql資料庫的存入;

(2)将相關msgid放入kestrel消息隊列就算消息推送成功;

Mongrel沒有使用任何方式去通知作者、讀者,讓他們重新拉取消息。

上述工作方式,反映了twitter架構設計“分拆”的理念:

(1)将一個完整的流程分拆成獨立工作的子流程,一個工作可以由各個服務負責(三層架構本身是一種分拆);

(2)多機器之間協作,細化資料流與控制流,并強調其分離;

twitter業務流程的分隔,是一種事件驅動式的設計,主要展現在兩個方面:

(1)Mongrel與mysql的分離,前者不直接插手mysql的操作,而委托memcached全權負責;

(2)上傳、下載下傳邏輯分離:隻通過kestrel隊列來傳遞指令;