天天看點

Twitter(一)

Twitter的核心業務邏輯,在于Following和Be followed。[5]

  進入Twitter個人首頁,你會看到你following的那些作者,最近發表的微部落格。所謂微部落格,就是一則短信,Twitter規定,短信的長度不得超過140個字。短信不僅可以包含普通文字資訊,也可以包含URL,指向某個網頁,或者照片及視訊等等。這就是following的過程。

  當你寫了一則短信并發表以後,你的followers會立刻在他們的個人首頁中看到你寫的最新短信。這就是befollowed的過程。

  實作這個業務流程似乎很容易。

  1.為每一個注冊使用者訂制一個Be-followed的表,主要内容是每一個follower的ID。同時,也訂制一個Following的表,主要内容是一個following作者的ID。

  2.當使用者打開自己的個人空間時,Twitter先查閱Following表,找到所有following的作者的ID。然後去資料庫讀取每一位作者最近寫的短信。彙總後按時間順序顯示在使用者的個人首頁上。

  3.當使用者寫了一則短信時,Twitter先查閱Be-followed表,找到所有followers的IDs。然後逐個更新那些followers的首頁。

  如果有follower正在閱讀他的Twitter個人首頁,首頁裡暗含的JavaScript會自動每隔幾十秒,通路一下Twitter伺服器,檢查正在看的這個個人首頁是否有更新。如果有更新,立刻下載下傳新的首頁内容。這樣follower就能讀到最新發表的短信了。

  從作者發表到讀者擷取,中間的延遲,取決于JavaScript更新的間隔,以及Twitter伺服器更新每個follower的首頁的時間。

 從系統架構上來說,似乎傳統的三層架構(Three-tier architecture[6]),足夠滿足這個業務邏輯的需要。事實上,最初的Twitter系統架構,的确就是三層架構。

2006年5月Twitter剛上線的時候,為了簡化網站的開發,他們使用了Ruby-On-Rails工具,而Ruby-On-Rails的設計思想,就是三層架構。

  1. 表示層(Presentation Tier) 用的工具是Apache WebServer,主要任務是解析HTTP協定,把來自不同使用者的,不同類型的請求,分發給邏輯層。

  2. 邏輯層 (Logic Tier)用的工具是Mongrel RailsServer,利用Rails現成的子產品,降低開發的工作量。

  3. 資料層 (Data Tier) 用的工具是MySQL資料庫。

先說資料層。

  Twitter 的服務,可以概括為兩個核心:1. 使用者,2.短信。使用者與使用者之間的關系,是追與被追的關系,也就是Following和Befollowed。對于一個使用者來說,他隻讀自己“追”的那些人寫的短信。而他自己寫的短信,隻有那些“追”自己的人才會讀。抓住這兩個核心,就不難了解Twitter的其它功能是如何實作的[7]。

  圍繞這兩個核心,就可以着手設計Data Schema,也就是存放在資料層(DataTier)中的資料的組織方式。不妨設定三個表[8]:

  1. 使用者表:使用者ID,姓名,登入名和密碼,狀态(線上與否)。

  2. 短信表:短信ID,作者ID,正文(定長,140字),時間戳。

  3. 使用者關系表,記錄追與被追的關系:使用者ID,他追的使用者IDs (Following),追他的使用者IDs (Befollowed)。

 

 再說邏輯層。

  當使用者發表一條短信的時候,執行以下五個步驟:

  1. 把該短信記錄到“短信表” 中去。

  2. 從“使用者關系表”中取出追他的使用者的IDs。

  3. 有些追他的使用者目前線上,另一些可能離線。線上與否的狀态,可以在“使用者表”中查到。過濾掉那些離線的使用者的IDs。

  4. 把那些追他的并且目前線上的使用者的IDs,逐個推進一個隊列(Queue)中去。

  5. 從這個隊列中,逐個取出那些追他的并且目前線上的使用者的IDs,并且更新這些人的首頁,也就是添加最新發表的這條短信。

  以上這五個步驟,都由邏輯層(LogicTier)負責。前三步容易解決,都是簡單的資料庫操作。最後兩步,需要用到一個輔助工具,隊列。隊列的意義在于,分離了任務的産生與任務的執行。

隊列的實作方式有多種,例如Apache Mina[9]就可以用來做隊列。但是Twitter團隊自己動手實作了一個隊列,Kestrel[10,11]。Mina與Kestrel,各自有什麼優缺點,似乎還沒人做過詳細比較。

  不管是Kestrel還是Mina,看起來都很複雜。或許有人問,為什麼不用簡單的資料結構來實作隊列,例如動态連結清單,甚至靜态數組?如果邏輯層隻在一台伺服器上運作,那麼對動态連結清單和靜态數組這樣的簡單的資料結構,稍加改造,的确可以當作隊列使用。Kestrel和Mina這些“重量級”的隊列,意義在于支援聯絡多台機器的、分布式的隊列。在本系列以後的篇幅中,将會重點介紹。

最後說說表示層。

  表述層的主要職能有兩 個:1. HTTP協定處理器(HTTPProcessor),包括拆解接收到的使用者請求,以及封裝需要發出的結果。2.分發器(Dispatcher),把接收到的使用者請求,分發給邏輯層的機器處理。如果邏輯層隻有一台機器,那麼分發器無意義。但是如果邏輯層由多台機器組成,什麼樣的請求,發給邏輯層裡面哪一台機器,就大有講究了。邏輯層裡衆多機器,可能各自專門負責特定的功能,而在同功能的機器之間,要分攤工作,使負載均衡。

  通路Twitter網站的,不僅僅是浏覽器,而且還有手機,還有像QQ那樣的電腦桌面工具,另外還有各式各樣的網站插件,以便把其它網站聯系到Twitter.com上來[12]。是以,Twitter的通路者與Twitter網站之間的通訊協定,不一定是HTTP,也存在其它協定。

三層的Twitter架構,主要是針對HTTP協定的終端。但是對于其它協定的終端,Twitter的架構沒有明顯地劃分成三層,而是把表示層和邏輯層合二為一,在Twitter的文獻中,這二合一經常被稱為“API”。

綜上所述,一個能夠完成Twitter基本功能的、簡單的架構如Figure 1所示。或許大家會覺得疑惑,這麼出名的網站,架構就這麼簡單?Yes andNo,2006年5月Twitter剛上線的時候,Twitter架構與Figure1差距不大,不一樣的地方在于加了一些簡單的緩存(Cache)。即便到了現在,Twitter的架構依然可以清晰地看到Figure 1的輪廓。

Twitter(一)

Figure 1. The essential 3-tier of Twitter architecture

Cache == Cash,緩存等于現金收入。雖然這話有點誇張,但是正确使用緩存,對于大型網站的建設是至關重要的大事。網站在回應使用者請求時的反應速度,是影響使用者體驗的一大因素。而影響速度的原因有很多,其中一個重要的原因在于硬碟的讀寫(Disk IO)。

  Table 1 比較了記憶體(RAM),硬碟(Disk),以及新型的閃存(Flash),在讀寫方面的速度比較。硬碟的讀寫,速度比記憶體的慢了百萬倍。是以,要提高網站的速度,一個重要措施是盡可能把資料緩存在記憶體裡。當然,在硬碟裡也必須保留一個拷貝,以此防範萬一由于斷電,記憶體裡的資料丢失的情況發生。

Twitter(一)

Table 1. Storage media comparison of Disk, Flash and RAM [13]

  Twitter 工程師認為,一個使用者體驗良好的網站,當一個使用者請求到達以後,應該在平均500ms以内完成回應。而Twitter的理想,是達到200ms- 300ms的反應速度[17]。是以在網站架構上,Twitter大規模地,多層次多方式地使用緩存。Twitter在緩存使用方面的實踐,以及從這些實踐中總結出來的經驗教訓,是Twitter網站架構的一大看點。

Twitter(一)

Figure 2. Twitter architecture with Cache

哪裡需要緩存?越是Disk IO頻繁的地方,越需要緩存。

前面說到,Twitter業務的核心有兩個,使用者和短信(Tweet)。圍繞這兩個核心,資料庫中存放着若幹表,其中最重要的有三個,如下所示。這三個表的設定,是旁觀者的猜測,不一定與Twitter的設定完全一緻。但是萬變不離其宗,相信即便有所不同,也不會本質差別。

1. 使用者表:使用者ID,姓名,登入名和密碼,狀态(線上與否)。

2. 短信表:短信ID,作者ID,正文(定長,140字),時間戳。

3. 使用者關系表,記錄追與被追的關系:使用者ID,他追的使用者IDs (Following),追他的使用者IDs (Be followed)。

有沒有必要把這幾個核心的資料庫表統統存放到緩存中去?Twitter的做法是把這些表拆解,把其中讀寫最頻繁的列放進緩存。

1. Vector Cache and Row Cache

具體來說,Twitter工程師認為最重要的列是IDs。即新發表的短信的IDs,以及被頻繁閱讀的熱門短信的IDs,相關作者的IDs,以及訂閱這些作者的讀者的IDs。把這些IDs存放進緩存 (Stores arrays of tweet pkeys [14])。在Twitter文獻中,把存放這些IDs的緩存空間,稱為Vector Cache [14]。

Twitter工程師認為,讀取最頻繁的内容是這些IDs,而短信的正文在其次。是以他們決定,在優先保證Vector Cache所需資源的前提下,其次重要的工作才是設立Row Cache,用于存放短信正文。

命中率(Hit Rate or Hit Ratio)是測量緩存效果的最重要名額。如果一個或者多個使用者讀取100條内容,其中99條内容存放在緩存中,那麼緩存的命中率就是99%。命中率越高,說明緩存的貢獻越大。

設立Vector Cache和Row Cache後,觀測實際運作的結果,發現Vector Cache的命中率是99%,而Row Cache的命中率是95%,證明了Twitter工程師早先押注的,先IDs後正文的判斷。

Vector Cache和Row Cache,使用的工具都是開源的MemCached [15]。

2. Fragment Cache and Page Cache

前文說到,通路Twitter網站的,不僅僅是浏覽器,而且還有手機,還有像QQ那樣的電腦桌面工具,另外還有各式各樣的網站插件,以便把其它網站聯系到 Twitter.com上來[12]。接待這兩類使用者的,是以Apache Web Server為門戶的Web通道,以及被稱為“API”的通道。其中API通道受理的流量占總流量的80%-90% [16]。

是以,繼Vector Cache和Row Cache以後,Twitter工程師們把進一步建築緩存的工作,重點放在如何提高API通道的反應速度上。

讀者頁面的主體,顯示的是一條又一條短信。不妨把整個頁面分割成若幹局部,每個局部對應一條短信。所謂Fragment,就是指頁面的局部。除短信外,其它内容例如Twitter logo等等,也是Fragment。如果一個作者擁有衆多讀者,那麼緩存這個作者寫的短信的布局頁面(Fragment),就可以提高網站整體的讀取效率。這就是Fragment Cache的使命。

對于一些人氣很旺的作者,讀者們不僅會讀他寫的短信,而且會通路他的首頁,是以,也有必要緩存這些人氣作者的個人首頁。這就是Page Cache的使命。

Fragment Cache和Page Cache,使用的工具也是MemCached。

觀測實際運作的結果,Fragment Cache的命中率高達95%,而Page Cache的命中率隻有40%。雖然Page Cache的命中率低,但是它的内容是整個個人首頁,是以占用的空間卻不小。為了防止Page Cache争奪Fragment Cache的空間,在實體部署時,Twitter工程師們把Page Cache分離到不同的機器上去。

3. HTTP Accelerator

解決了API通道的緩存問題,接下去Twitter工程師們着手處理Web通道的緩存問題。經過分析,他們認為Web通道的壓力,主要來自于搜尋。尤其是面臨突發事件時,讀者們會搜尋相關短信,而不理會這些短信的作者,是不是自己“追”的那些作者。

要降低搜尋的壓力,不妨把搜尋關鍵詞,及其對應的搜尋結果,緩存起來。Twitter工程師們使用的緩存工具,是開源項目Varnish [18]。

比較有趣的事情是,通常把Varnish部署在Web Server之外,面向Internet的位置。這樣,當使用者通路網站時,實際上先通路Varnish,讀取所需内容。隻有在Varnish沒有緩存相應内容時,使用者請求才被轉發到Web Server上去。而Twitter的部署,卻是把Varnish放在Apache Web Server内側[19]。原因是Twitter的工程師們覺得Varnish的操作比較複雜,為了降低Varnish崩潰造成整個網站癱瘓的可能性,他們便采取了這種古怪而且保守的部署方式。

Apache Web Server的主要任務,是解析HTTP,以及分發任務。不同的Mongrel Rails Server負責不同的任務,但是絕大多數Mongrel Rails Server,都要與Vector Cache和Row Cache聯系,讀取資料。Rails Server如何與MemCached聯系呢?Twitter工程師們自行開發了一個Rails插件(Gem),稱為CacheMoney。

雖然Twitter沒有公開Varnish的命中率是多少,但是[17]聲稱,使用了Varnish以後,導緻整個Twitter.com網站的負載下降了50%,參見Figure 3.

Twitter(一)

Figure 3. Cache decreases Twitter.com load by 50% [17]

如果說如何巧用Cache是Twitter的一大看點,那麼另一大看點是它的消息隊列(MessageQueue)。為什麼要使用消息隊列?[14]的解釋是“隔離使用者請求與相關操作,以便燙平流量高峰 (Move operationsout of the synchronous request cycle, amortize load overtime)”。

  為了了解這段話的意思,不妨來看一個執行個體。2009年1月20日星期二,美國總統BarackObama就職并發表演說。作為美國曆史上第一位黑人總統,Obama的就職典禮引起強烈反響,導緻Twitter流量猛增,如Figure4 所示。

其中洪峰時刻,Twitter網站每秒鐘收到350條新短信,這個流量洪峰維持了大約5分鐘。根據統計,平均每個Twitter使用者被120人“追”,這就是說,這350條短信,平均每條都要發送120次 [16]。這意味着,在這5分鐘的洪峰時刻,Twitter網站每秒鐘需要發送350 x120 = 42,000條短信。

  面對洪峰,如何才能保證網站不崩潰?辦法是迅速接納,但是推遲服務。打個比方,在晚餐高峰時段,餐館常常客滿。對于新來的顧客,餐館服務員不是拒之門外,而是讓這些顧客在休息廳等待。這就是[14]所說的“隔離使用者請求與相關操作,以便燙平流量高峰”。

如何實施隔離呢?當一位使用者通路Twitter網站時,接待他的是Apache WebServer。Apache做的事情非常簡單,它把使用者的請求解析以後,轉發給Mongrel RailsSever,由Mongrel負責實際的處理。而Apache騰出手來,迎接下一位使用者。這樣就避免了在洪峰期間,使用者連接配接不上Twitter網站的尴尬局面。

  雖然Apache的工作簡單,但是并不意味着Apache可以接待無限多的使用者。原因是Apache解析完使用者請求,并且轉發給Mongrel Server以後,負責解析這個使用者請求的程序(process),并沒有立刻釋放,而是進入空循環,等待MongrelServer傳回結果。這樣,Apache能夠同時接待的使用者數量,或者更準确地說,Apache能夠容納的并發的連接配接數量(concurrentconnections),實際上受制于Apache能夠容納的程序數量。Apache系統内部的程序機制參見Figure5,其中每個Worker代表一個程序。

Apache能夠容納多少個并發連接配接呢?[22]的實驗結果是4,000個,參見Figure6。如何才能提高Apache的并發使用者容量呢?一種思路是不讓連接配接受制于程序。不妨把連接配接作為一個資料結構,存放到記憶體中去,釋放程序,直到Mongrel Server傳回結果時,再把這個資料結構重新加載到程序上去。

  事實上Yaws WebServer[24],就是這麼做的[23]。是以,Yaws能夠容納80,000以上的并發連接配接,這并不奇怪。但是為什麼Twitter用Apache,而不用Yaws呢?或許是因為Yaws是用Erlang語言寫的,而Twitter工程師對這門新語言不熟悉 (But youneed in house Erlang experience [17])。

Twitter(一)

Figure 5. Apache web server system architecture [21]

Twitter(一)

Figure 6. Apache vs. Yaws. The horizonal axis shows the parallelrequests, the vertical one shows the throughput (KBytes/second).The red curve is Yaws, running on NFS. The blue one is Apache,running on NFS, while the green one is also Apache but on a localfile system. Apache dies at about 4,000 parallel sessions, whileYaws is still functioning at over 80,000 parallel connections.[22]

【5】資料流與控制流

  前文說到,Twitter有兩大看點,緩存(Cache) 與消息隊列(Message Queue)。消息隊列的作用,是“隔離使用者請求與相關操作,以便燙平流量高峰 (Move operations out of the synchronous request cycle, amortize load over time)”。

  通過讓Apache程序空循環的辦法,迅速接納使用者的通路,推遲服務,說白了是個緩兵之計,目的是讓使用者不至于收到“HTTP 503”錯誤提示,“503錯誤”是指“服務不可用(Service Unavailable)”,也就是網站拒絕通路。

  大禹治水,重在疏導。真正的抗洪能力,展現在蓄洪和洩洪兩個方面。蓄洪容易了解,就是建水庫,要麼建一個超大的水庫,要麼造衆多小水庫。洩洪包括兩個方面,1. 引流,2. 管道。

  對于Twitter系統來說,龐大的伺服器叢集,尤其是以MemCached為主的衆多的緩存,展現了蓄洪的容量。引流的手段是Kestrel消息隊列,用于傳遞控制指令。管道是機器與機器之間的資料傳輸通道,尤其是通往MemCached的資料通道。管道的優劣,在于是否通暢。

  Twitter的設計,與大禹的做法,形相遠,實相近。Twitter系統的抗洪措施,展現在有效地控制資料流,保證在洪峰到達時,能夠及時把資料疏散到多個機器上去,進而避免壓力過度集中,造成整個系統的癱瘓。

  2009年6月,Purewire公司通過爬Twitter網站,跟蹤Twitter使用者之間“追”與“被追”的關系,估算出Twitter使用者總量在7,000,000左右 [26]。在這7百萬使用者中,不包括那些既不追别人,也不被别人追的孤立使用者。也不包括孤島人群,孤島内的使用者隻互相追與被追,不與外界聯系。如果加上這些孤立使用者和孤島使用者群,目前Twitter的使用者總數,或許不會超過1千萬。

  截止2009年3月,中國移動使用者數已達4.7億戶[27]。如果中國移動的飛信[28] 和139說客[29] 也想往Twitter方向發展,那麼飛信和139的抗洪能力應該設計到多少呢?簡單講,需要把Twitter系統的現有規模,至少放大47倍。是以,有人這樣評論移動網際網路産業,“在中國能做到的事情,在美國一定能做到。反之,不成立”。

Twitter(一)

Figure 7. Twitter internal flows

 下面舉個簡單的例子,剖析一下Twitter網站内部的流程,借此考察Twitter系統有哪些機制,去實作抗洪的三要素,“水庫”、“引流”和“管道”。

  假設有兩個作者,通過浏覽器,在Twitter網站上發表短信。有一個讀者,也通過浏覽器,通路網站并閱讀他們寫的短信。

  1. 作者的浏覽器與網站建立連接配接,Apache Web Server配置設定一個程序(Worker Process)。作者登入,Twitter查找作者的ID,并作為Cookie,記憶在HTTP郵包的頭屬性裡。

  2. 浏覽器上傳作者新寫的短信(Tweet),Apache收到短信後,把短信連同作者ID,轉發給Mongrel Rails Server。然後Apache程序進入空循環,等待Mongrel的回複,以便更新作者首頁,把新寫的短信添加上去。

  3. Mongrel收到短信後,給短信配置設定一個ID,然後把短信ID與作者ID,緩存到Vector MemCached伺服器上去。

  同時,Mongrel讓Vector MemCached查找,有哪些讀者“追”這位作者。如果Vector MemCached沒有緩存這些資訊,Vector MemCached自動去MySQL資料庫查找,得到結果後,緩存起來,以備日後所需。然後,把讀者IDs回複給Mongrel。

  接着,Mongrel把短信ID與短信正文,緩存到Row MemCached伺服器上去。

  4. Mongrel通知Kestrel消息隊列伺服器,為每個新短信開設一個隊列,隊列的名稱中隐含短信ID。

  對應于每個短信,Mongrel已經從Vector MemCached那裡知道,有哪些讀者追這條短信的作者。Mongrel把這些讀者的IDs,逐個放進這個短信的隊列。假如短信二的作者是作者二,他有兩個讀者,Follower7和Follower3,那麼第二個短信的隊列中将有兩個消息,分别包括Follower7和Follower3的IDs。

  5. 同一台Mongrel Server,或者另一台Mongrel Server,在處理某個Kestrel隊列中的消息前,從這個隊列的名稱中解析出相應的短信ID。

  然後Mongrel從Row MemCached緩存器中,查找對應于這個短信ID的短信正文。

  Mongrel從Kestrel隊列中,逐個提取消息,解析消息中包含的讀者ID。得到讀者ID,以及短信正文後,Mongrel更新該讀者的首頁,添加上這條短信的正文。同時,也更新作者的首頁,也添加這條短信的正文。

  6. Mongrel把更新後的作者的首頁,傳遞給正在空循環的Apache的程序。該程序把作者首頁主動傳送(push)給作者的浏覽器。

  如果讀者的浏覽器事先已經登入Twitter網站,建立連接配接,那麼Apache給該讀者也配置設定了一個程序,該程序也處于空循環狀态。Mongrel把更新後的讀者的首頁,傳遞給相應程序,該程序把讀者首頁主動傳遞給讀者的浏覽器。

  咋一看,流程似乎不複雜。“水庫”,“引流”和“管道”,這抗洪三要素展現在哪裡呢?盛名之下的Twitter,妙處何在?值得細究的看點很多。

【6】流量洪峰與雲計算

  上一篇曆數了一則短信從發表到被閱讀,Twitter業務邏輯所經曆的6個步驟。表面上看似乎很乏味,但是細細咀嚼,把每個步驟展開來說,都有一段故事。

  美國年度橄榄球決賽,綽号超級碗(Super Bowl)。Super Bowl在美國的收視率,相當于中國的央視春節晚會。2008年2月3日,星期天,該年度Super Bowl如期舉行。紐約巨人隊(Giants),對陣波士頓愛國者隊(Patriots)。這是兩支實力相當的球隊,決賽結果難以預料。比賽吸引了近一億美國人觀看電視實況轉播。

  對于Twitter來說,可以預料的是,比賽進行過程中,Twitter流量必然大漲。比賽越激烈,流量越高漲。Twitter無法預料的是,流量究竟會漲到多少,尤其是洪峰時段,流量會達到多少。

  根據[31]的統計,在Super Bowl比賽進行中,每分鐘的流量與當日平均流量相比,平均高出40%。在比賽最激烈時,更高達150%以上。與一周前,2008年1月27日,一個平靜的星期天的同一時段相比,流量的波動從平均10%,上漲到40%,最高波動從35%,上漲到150%以上。

由此可見,Twitter流量的波動十分可觀。對于Twitter公司來說,如果預先購置足夠的裝置,以承受流量的變化,尤其是重大事件導緻的洪峰流量,那麼這些裝置在大部分時間處于閑置狀态,非常不經濟。但是如果缺乏足夠的裝置,那麼面對重大事件,Twitter系統有可能崩潰,造成的後果是使用者流失。

  怎麼辦?辦法是變買為租。Twitter公司自己購置的裝置,其規模以應付無重大事件時的流量壓力為限。同時租賃雲計算平台公司的裝置,以應付重大事件來臨時的洪峰流量。租賃雲計算的好處是,計算資源實時配置設定,需求高的時候,自動配置設定更多計算資源。

  Twitter公司在2008年以前,一直租賃Joyent公司的雲計算平台。在2008年2月3日的Super Bowl即将來臨之際,Joyent答應Twitter,在比賽期間免費提供額外的計算資源,以應付洪峰流量[32]。但是詭異的是,離大賽隻剩下不到4天,Twitter公司突然于1月30日晚10時,停止使用Joyent的雲計算平台,轉而投奔Netcraft [33,34]。

  Twitter棄Joyent,投Netcraft,其背後的原因是商務糾葛,還是擔心Joyent的服務不可靠,至今仍然是個謎。

  變買為租,應對洪峰,這是一個不錯的思路。但是租來的計算資源怎麼用,又是一個大問題。檢視一下[35],不難發現Twitter把租賃來的計算資源,大部分用于增加Apache Web Server,而Apache是Twitter整個系統的最前沿的環節。

  為什麼Twitter很少把租賃來的計算資源,配置設定給Mongrel Rails Server,MemCached Servers,Varnish HTTP Accelerators等等其它環節?在回答這個問題以前,我們先複習一下前一章“資料流與控制流”的末尾,Twitter從寫到讀的6個步驟。

  這6個步驟的前2步說到,每個通路Twitter網站的浏覽器,都與網站保持長連接配接。目的是一旦有人發表新的短信,Twitter網站在500ms以内,把新短信push給他的讀者。問題是在沒有更新的時候,每個長連接配接占用一個Apache的程序,而這個程序處于空循環。是以,絕大多數Apache程序,在絕大多數時間裡,處于空循環,是以占用了大量資源。

  事實上,通過Apache Web Servers的流量,雖然隻占Twitter總流量的10%-20%,但是Apache卻占用了Twitter整個伺服器叢集的50%的資源[16]。是以,從旁觀者角度來看,Twitter将來勢必罷黜Apache。但是目前,當Twitter配置設定計算資源時,迫不得已,隻能優先保證Apache的需求。

  迫不得已隻是一方面的原因,另一方面,也表明Twitter的工程師們,對其系統中的其它環節,太有信心了。

  在第四章“抗洪需要隔離”中,我們曾經打過一個比方,“在晚餐高峰時段,餐館常常客滿。對于新來的顧客,餐館服務員不是拒之門外,而是讓這些顧客在休息廳等待”。對于Twitter系統來說,Apache充當的角色就是休息廳。隻要休息廳足夠大,就能暫時穩住使用者,換句行話講,就是不讓使用者收到HTTP-503的錯誤提示。

  穩住使用者以後,接下去的工作是高效率地提供服務。高效率的服務,展現在Twitter業務流程6個步驟中的後4步。為什麼Twitter對這4步這麼有信心?

Twitter(一)

Figure 8. Twitter traffic during Super Bowl, Sunday, Feb 3, 2008 [31]. The blue line represents the percentage of updates per minute during the Super Bowl normalized to the average number of updates per minute during the rest of the day, with spikes annotated to show what people were twittering about. The green line represents the traffic of a “regular” Sunday, Jan 27, 2008.

Reference:

  [7] Tweets中常用的工具 (http://www.ccthere.com/article/2383833)

  [8] 建構基于PHP的微部落格服務(http://webservices.ctocio.com.cn/188/9092188.shtml)

  [9] Apache Mina Homepage (http://mina.apache.org/)

  [10] Kestrel Readme (http://github.com/robey/kestrel)

  [11] A Working Guide to Kestrel.(http://github.com/robey/kestrel/blob/master/docs/guide.md)

  [12] Alphabetical List of Twitter Services and Applications(http://en.wikipedia.org/wiki/List_of_Twitter_services_and_applications)

  [13] How flash changes the DBMS world. (http://hansolav.net/blog/content/binary/HowFlashMemory.pdf)

  [14] Improving running component of Twitter. (http://qconlondon.com/london-2009/file?path=/qcon-london-2009/slides/EvanWeaver_ImprovingRunningComponentsAtTwitter.pdf)

  [15] A high-performance, general-purposed, distributed memory object caching system. (http://www.danga.com/memcached/)

  [16] Updating Twitter without service disruptions. (http://gojko.net/2009/03/16/qcon-london-2009-upgrading-twitter-without-service-disruptions/)

  [17] Fixing Twitter. (http://assets.en.oreilly.com/1/event/29/Fixing_Twitter_Improving_the_Performance_and_Scalability_of_the_World_s_Most_Popular_Micro-blogging_Site_Presentation%20Presentation.pdf)

  [18] Varnish, a high-performance HTTP accelerator. (http://varnish.projects.linpro.no/)

  [19] How to use Varnish in Twitter.com? (http://projects.linpro.no/pipermail/varnish-dev/2009-February/000968.html)

  [20] CacheMoney Gem, an open-source write-through caching library. (http://github.com/nkallen/cache-money)

  [16] Updating Twitter without service disruptions.(http://gojko.net/2009/03/16/qcon-london-2009-upgrading-twitter-without-service-disruptions/)

  [17] Fixing Twitter.(http://assets.en.oreilly.com/1/event/29/Fixing_Twitter_Improving_the_Performance_and_Scalability_of_the_World_s_Most_Popular_Micro-blogging_Site_Presentation%20Presentation.pdf)

  [21] Apache system architecture.(http://www.fmc-modeling.org/download/publications/groene_et_al_2002-architecture_recovery_of_apache.pdf)

  [22] Apache vs Yaws.(http://www.sics.se/~joe/apachevsyaws.html)

  [23] 質疑Apache和Yaws的性能比較.(http://www.javaeye.com/topic/107476)

  [24] Yaws Web Server. (http://yaws.hyber.org/)

  [25] Erlang Programming Language. (http://www.erlang.org/)

 [30] Giants and Patriots draws 97.5 million US audience to the Super Bowl. (http://www.reuters.com/article/topNews/idUSN0420266320080204)

  [31] Twitter traffic during Super Bowl 2008. (http://blog.twitter.com/2008/02/highlights-from-superbowl-sunday.html)

  [32] Joyent provides Twitter free extra capacity during the Super Bowl 2008. (http://blog.twitter.com/2008/01/happy-happy-joyent.html)

  [33] Twitter stopped using Joyent’s cloud at 10PM, Jan 30, 2008. (http://www.joyent.com/joyeurblog/2008/01/31/twitter-and-joyent-update/)

  [34] The hasty divorce for Twitter and Joyent. (http://www.datacenterknowledge.com/archives/2008/01/31/hasty-divorce-for-twitter-joyent/)

  [35] The usage of Netcraft by Twitter. (http://toolbar.netcraft.com/site_report?url=http://twitter.com)