瞭解Instagram背後的技術

發表於2013-04-26

來源:丁雪豐@infoq

剛被Facebook以10億美金收購的著名手機照片分享應用Instagram最近吸引了無數人的眼球,Android版本登陸Google Play不到一個月下載量就突破1000萬,總使用者數即將超過5000萬。Instagram聯合創始人Mike Krieger說他們用了8周時間打造了最初的Instagram,但現在的系統肯定已經今非昔比。Instagram技術團隊曾發表過一篇文章,介紹了Instagram背後的技術,日前Mike Krieger在名為Scaling Instagram的演講裡,又介紹了更多細節,讓人們能瞭解到5名技術人員是如何支撐起整個系統的。

一張照片上傳的過程是這樣的:

1、採用同步的方式寫入媒體資料庫

2、如果照片上有地理位置標籤,則以非同步的方式將照片提交給Solr進行索引

3、將照片的ID加入每個關注者的列表裡,該列表儲存在Redis之中

4、在顯示Feed時,選取一小部分照片ID,在Memcached裡進行查詢

在設計系統時,Instagram的設計哲學是簡單、為最小化運維負擔進行優化並監控一切內容;其核心原則是保持簡單,不要重複發明輪子,儘可能使用經過驗證、穩定可靠的技術。

由於只有5名技術人員(其中僅2.5名後端工程師),精力有限,選擇Amazon的雲服務是個不錯的選擇。目前他們使用了超過100個EC2例項用於提供各種服務,執行的作業系統是Ubuntu 11.04,之前的一些版本在高流量時表現不夠穩定。在負載均衡方面,他們使用Amazon的Elastic Load Balancer實現負載均衡,後端執行了3個Nginx例項,SSL只到ELB上為止,降低了Nginx上的CPU負載。DNS和CDN分別由Amazon的Route 53CloudFront提供,所有的照片都存放在S3上,目前已經有幾TB的規模了。

用於處理請求的應用伺服器執行於Amazon High-CPU Extra-Large Instance之上,由於他們的請求更多是CPU密集型的,因此這能更好地平衡CPU與記憶體。採用的開發框架是Django,WSGI伺服器是Gunicorn,通過Fabric在所有機器上進行並行部署,一次部署僅需幾秒鐘。

大多數資料都存放在PostgreSQL裡,主分片叢集執行於12個High-Memory Quadruple Extra-Large Instance(68.4GB記憶體)上,另有12個位於不同可用區裡的副本,通過repmgrStreaming Replication的方式進行同步。由於Elastic Block Store的磁碟IOPS不高,因此需要將正在使用的資料都載入到記憶體裡,vmtouch能幫助管理記憶體中的資料。他們在EBS上使用mdadm實現了軟體Raid,以此提升寫吞吐量;資料庫的檔案系統用的是XFS,在從庫獲取快照時,會先凍結RAID陣列,保證快照的一致性。

應用程式在連線資料庫時,由Pgbouncer建 立連線池。目前,Instagram的資料按照使用者ID進行分片,某些分片可能會超出物理節點的容量上限,為此他們將資料分成了很多個邏輯分片,對映到少 數幾個物理節點之上;當一個節點被填滿之後,可以將某些邏輯分片移到別的節點上,以緩解該節點的壓力。隨著資料量的增長,以後他們也會進行垂直分 區,Django DB Router能讓一切輕鬆不少。

Instagram也大量使用Redis來存放複雜的物件(物件的大小做了一定的限制),用於主Feed、活動Feed、會話系統及其他相關係統。因為要將Redis的所有資料都放在記憶體裡,此處同樣也用了High-Memory Quadruple Extra-Large Instance,並對資料做了分片。當Redis例項的請求達到4萬/秒後,它漸漸成為了瓶頸,於是Redis也做了主從複製,副本的資料會經常匯出到磁碟上,通過EBS快照進行備份。

除了Redis,他們還使用Memcached來做快取,目前執行了6個例項,應用伺服器通過pylibmclibmemcached進行連線。雖然Amazon提供了Elastic Cache服務,但該服務的價格並不便宜,相比之下,還是執行自己的Memcached例項比較划算。非同步任務佇列使用的是Gearman,目前有大約200個工作程式來處理各種任務,比如把照片分享到Twitter和Facebook,通知使用者有新照片等等。Pyapns已經處理了十億的推送通知,非常穩定,他們還自己開發了基於Node.js的node2dm,用於向Android裝置傳送推送通知。

監控方面,Instagram使用Munin以圖形化的方式呈現整個系統的執行狀況,還通過Python-Munin定製了一些外掛,用來顯示業務資料;網路守護程式Stated可以實時收集資料並做彙總;Dogslow會監控程式,一旦發現執行時間過長的程式,便會儲存該程式的快照,以便後續分析,比如響應時間超過1.5秒的請求,通常都是卡在Memcached的set()和get_many()方法上。對於Python的錯誤,只要登上Sentry就能實時獲取錯誤資訊。

HighScalability上還根據整理Mike Krieger的演講整理了一些值得借鑑的經驗,比如:

● 找那些你熟悉的技術和工具,在簡單的使用場景裡先做一些嘗試

● 不要使用兩個工具來處理同樣的任務

● 事先準備降級方案,以便在需要時降低負載

● 不要過度優化,或者希望能事先知道站點要擴充套件,對於一個初創的社交站點而言,沒什麼擴充套件性問題是解決不了的

● 如果一個辦法不行,趕快換下一個

如果您想進一步瞭解Instagram背後的技術細節,可以訪問其技術團隊的部落格

 

 

相關文章