架構學習筆記—Twitter

作爲140個字的締造者,twitter太簡單了,又太複雜了,簡單是因爲僅僅用140個字居然使有幾次世界性事件的傳播速度超過任何媒體,複雜是因爲要爲2億用戶提供這看似簡單的140個字的服務,這真的是因爲簡單,所以複雜。可是比較遺憾的是目前在中國大陸twitter是無法訪問的,但作爲一個愛好架構的程序猿,這道牆是必須得翻的,牆外的世界更精彩。今天就結合網絡上的一些資料,來淺談一下我對twitter網站架構的學習體會,希望給路過的朋友一點啓示.......

一、twitter網站基本情況概覽

  1. 截至2011年4月,twitter的註冊用戶約爲1.75億,並以每天300000的新用戶註冊數增長,但是其真正的活躍用戶遠遠小於這個數目,大部分註冊用戶都是沒有關注者或沒有關注別人的,這也是與facebook的6億活躍用戶不能相提並論的。
  2. twitter每月有180萬獨立訪問用戶數,並且75%的流量來自twitter.com以外的網站。每天通過API有30億次請求,每天平均產生5500次tweet,37%活躍用戶爲手機用戶,約60%的tweet來自第三方的應用。
  3. 平臺:Ruby on Rails 、Erlang 、MySQL 、Mongrel 、Munin 、Nagios 、Google Analytics 、AWStats 、Memcached

下圖是twitter的整體架構設計圖:

二、twitter的平臺

twitter平臺大致由twitter.com、手機以及第三方應用構成,如下圖所示:

其中流量主要以手機和第三方爲主要來源。

  • Ruby on Rails:web應用程序的框架
  • Erlang:通用的面向併發的編程語言,開源項目地址:http://www.erlang.org/
  • AWStats:實時日誌分析系統:開源項目地址:http://awstats.sourceforge.net/
  • Memcached:分佈式內存緩存組建
  • Starling:Ruby開發的輕量級消息隊列
  • Varnish:高性能開源HTTP加速器
  • Kestrel:scala編寫的消息中間件,開源項目地址:http://github.com/robey/kestrel
  • Comet Server:Comet是一種ajax長連接技術,利用Comet可以實現服務器主動向web瀏覽器推送數據,從而避免客戶端的輪詢帶來的性能損失。
  • libmemcached:一個memcached客戶端
  • 使用mysql數據庫服務器
  • Mongrel:Ruby的http服務器,專門應用於rails,開源項目地址:http://rubyforge.org/projects/mongrel/
  • Munin:服務端監控程序,項目地址:http://munin-monitoring.org/
  • Nagios:網絡監控系統,項目地址:http://www.nagios.org/

三、緩存

講着講着就又說到緩存了,確實,緩存在大型web項目中起到了舉足輕重的作用,畢竟數據越靠近CPU存取速度越快。下圖是twitter的緩存架構圖:

大量使用memcached作緩存

  • 例如,如果獲得一個count非常慢,你可以將count在1毫秒內扔入memcached
  • 獲取朋友的狀態是很複雜的,這有安全等其他問題,所以朋友的狀態更新後扔在緩存裏而不是做一個查詢。不會接觸到數據庫 
  • ActiveRecord對象很大所以沒有被緩存。Twitter將critical的屬性存儲在一個哈希裏並且當訪問時遲加載 
  • 90%的請求爲API請求。所以在前端不做任何page和fragment緩存。頁面非常時間敏感所以效率不高,但Twitter緩存了API請求

在memcached緩存策略中,又有所改進,如下所述:

1、創建一個直寫式向量緩存Vector Cache,包含了一個tweet ID的數組,tweet ID是序列化的64位整數,命中率是99%

2、加入一個直寫式行緩存Row Cache,它包含了數據庫記錄:用戶和tweets。這一緩存有着95%的命中率。

3、引入了一個直讀式的碎片緩存Fragmeng Cache,它包含了通過API客戶端訪問到的sweets序列化版本,這些sweets可以被打包成json、xml或者Atom格式,同樣也有着95%的命中率。

4、爲頁面緩存創建一個單獨的緩存池Page Cache。該頁面緩存池使用了一個分代的鍵模式,而不是直接的實效。

四、消息隊列

  • 大量使用消息。生產者生產消息並放入隊列,然後分發給消費者。Twitter主要的功能是作爲不同形式(SMS,Web,IM等等)之間的消息橋
  • 使用DRb,這意味着分佈式Ruby。有一個庫允許你通過TCP/IP從遠程Ruby對象發送和接收消息,但是它有點脆弱 
  • 移到Rinda,它是使用tuplespace模型的一個分享隊列,但是隊列是持久的,當失敗時消息會丟失 
  • 嘗試了Erlang 
  • 移到Starling,用Ruby寫的一個分佈式隊列 
  • 分佈式隊列通過將它們寫入硬盤用來挽救系統崩潰。其他大型網站也使用這種簡單的方式

五、總結

1、數據庫一定要進行合理索引

2、要儘可能快的認知你的系統,這就要你能靈活地運用各種工具了

3、緩存,緩存,還是緩存,緩存一切可以緩存的,讓你的應用飛起來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章