What Powers Instagram: Hundreds of Instances, Dozens of Technologies(譯文,轉)

add by zhj:html

      對譯文略有修改。原文發表時,Instagram還沒被Facebook收購,讀完只感受Instagram這三個後臺工程師真牛逼。python

三我的就能夠搞定1400萬註冊用戶。不過,另外一方面,咱們也看到,這三我的其實使用的都是現成的技術,至少從文章中看不出他nginx

們有什麼技術上的創新,固然就三我的搞創新也難了點,並且若是現有技術能基本上解決問題,對這樣一個小團隊而言,就不必git

本身開發新技術。最後,對他們願意把方案分享出來表示很是感謝。github

      該文章寫的比較早了,因此有些技術已經進行了更新,好比到2013年時,Instagram已經再也不使用gearman,而改成Celery+Rabbitmq,參見redis

他們在PyCon 2013上的演講PPT,messaging-at-scale-at-instagramapache

英文原文:http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances-dozens-ofdjango

譯文:http://www.cnblogs.com/xiekeli/archive/2012/05/23/2514108.html緩存

 

當咱們與其餘工程師偶遇和交流的時候,有一個問題常常被問及,「大家的技術架構(technology stack)是怎麼樣的」?咱們以爲從較高的層次來描述Instagram的全部構成系統是一件有趣的事情;將來你能夠期待更深刻的描述這些系統。這就是咱們的系統,僅僅1年時間,而且咱們活了下來,其中有一部分咱們一直在修改。一個小型團隊的初創公司,能夠在一年多一點時間發展到1400多萬用戶規模。 咱們選擇一種技術的核心原則是:服務器

  •   儘可能保持簡單
  •   不重複發明輪子
  •   儘可能用被驗證的可靠的技術

咱們將自頂向下進行介紹:

操做系統 / 主機

咱們在亞馬遜的 EC2上跑Ubuntu Linux 11.04 (「Natty Narwhal」)。咱們發現以前的版本在EC2上高流量的時候都會出現各類不可預測的問題( freezing episodes),但11.04已經穩定了。咱們只有3名工程師,咱們的需求依然在不斷的變化中,所以自託管主機不是咱們的選擇,也許將來當用戶量空前增加的時候,咱們會考慮。

負載均衡

每個對Instagram 服務器的訪問都會經過負載均衡服務器;咱們使用2臺nginx機 器作DNS輪詢。這種方案的缺點是當其中一臺退役時,須要花時間更新DNS。最近,咱們轉而使用亞馬遜的彈性負載均衡器,使用3個NGINX 實例能夠實現調入調出(若是有哪一個NGINX健康檢查失敗,則自動剔除);咱們同時在 ELB 層停掉了 SSL , 以緩解nginx的 CPU 壓力。咱們使用亞馬遜的Route53做爲DNS,他們最近在AWS控制檯上爲Route53增長了一個很好的GUI工具。

應用服務器

接下來是應用服務器用來處理咱們的請求。咱們在亞馬遜的High-CPU Extra-Large機器上運行了Django ,隨着使用量的增加,咱們已經在25臺主機上跑Django實例了(幸運地,由於是無狀態的,因此很是便於水平擴展)。咱們發現咱們的特定工做負載是屬於CPU bound而不是memory bound,所以High-CPU Extra-Large類型的實例恰好提供了合適的比重(CPU和內存)。

咱們使用 http://gunicorn.org/ 做爲咱們的WSGI服務器;咱們曾經使用mod_wsgi 和Apache,可是發現Gunicorn 更容易配置,且對CPU的要求更低。爲了一次在多個實例上執行命令(像部署代碼),咱們使用FabricFabric最近增長了並行模式,所以部署只須要花費幾秒鐘。

數據存儲

咱們大部分數據(用戶信息,照片的元數據、標籤等)存儲在PostgreSQL中;咱們 以前已經說了關於如何基於不一樣的Postgres 實例進行切分的。咱們的主要分片集羣包含12個Quadruple Extra-Large內存雲主機(每一個都有副本,且主副在不一樣區域);

咱們發現亞馬遜的網絡磁盤系統(EBS)每秒的尋道能力不夠,所以,將咱們全部工做集放在內存中就變得尤其重要。爲了得到合理的性能,建立了軟 RAID 以提高 IO 能力,使用的 Mdadm 工具進行 RAID 管理;

順便提一下,咱們發現vmtouch用來管理內存數據是個極好的工具,尤爲是在故障轉移時,從一臺機器到另外一臺機器,甚至沒有活動的內存概要文件的狀況。這裏是腳本,用來解析運行於一臺機器上的vmtouch 輸出並打印出相應vmtouch命令,在另外一臺機器上執行,用於匹配他當前的內存狀態;

咱們全部的PostgreSQL實例都是運行於主-備模式,基於流複製,而且咱們使用EBS快照常常備份咱們的系統。爲了保證咱們的快照的一致性(原始靈感來源於ec2-consistent-snapshot)咱們使用XFS做爲咱們的文件系統,經過XFS,當進行快照時,咱們能夠凍結&解凍RAID陣列。爲了進行流複製,咱們最愛的工具是repmgr

對於從咱們的應用服務器鏈接到數據,咱們很早就使用了Pgbouncer作 鏈接池,此舉對性能有巨大的影響。咱們發現Christophe Pettus的博客 有大量的關於Django、PostgreSQL 和Pgbouncer 祕訣的資源。

照片直接存儲在Amazon S3,當前已經存儲了幾T的照片數據。咱們使用亞馬遜的CloudFront 做爲咱們的CDN,這加快了全世界用戶的照片加載時間(像日本,咱們第二最受歡迎的國家)

咱們也普遍的使用了Redis ; 咱們的main feed、activity feed、sessions系統(這裏是咱們的Django session backend),和其餘 相關係統 都使用了Redis。 由於全部的Redis數據都須要放在內存中,所以咱們最後使用了幾個Quadruple Extra-Large Memory雲主機用於跑Redis。咱們的Redis也是運行於主-備模式,而且經 常將DB保存到磁盤,最後使用EBS快照備份這些數據(咱們發如今主機上進行導出太費勁了)。因爲Redis 容許寫入備份,使得在線故障轉移很是方便,轉移到一臺新的Redis 機器,而不須要停機。

對於咱們的geo-search API,咱們一直使用PostgreSQL了不少個月,不事後來遷移到了Apache Solr.他有一套簡單的JSON接口,這樣咱們的應用程序相關的,只是另外一套API而已。

最後,和任何現代Web服務同樣,咱們使用了Memcached 作緩存,而且當前已經使用了6個Memcached 實例,咱們使用pylibmc & libmemcached進行鏈接。亞馬遜最近發佈了一個彈性緩存服務,可是它並不比運行咱們本身的實例便宜,所以咱們尚未切換上去;

任務隊列&推送通知

當一個用戶決定分享一張Instagram 的照片到Twitter 或Facebook,或者是當咱們須要通知一個 實時訂閱者有一張新的照片貼出,咱們將這個任務推到 Gearman, 一個任務隊列系統。經過任務隊列異步執行意味着媒體上傳能夠很快完成(即發一條instagram很快),而「重擔」能夠在後臺運行。咱們大約有200個消費者(都用Python寫的),它們消費隊列中的任務。咱們的feed fan-out也使用了Gearman,這樣posting就會響應新用戶,由於他有不少followers。

對於消息推送,咱們找到的最划算的方案是https://github.com/samuraisam/pyapns,一個開源的Twisted 服務,已經爲咱們處理了超過10億條通知,而且絕對可靠。

監視

對於100多個實例,監控變得很是重要。咱們使用Munin進行圖形化度量,若是有什麼超出了正常範圍,那會提醒咱們。咱們基於 Python-Munin,也寫了不少Munin 插件。用於圖形化度量非系統級的東西(例如,每分鐘的簽入人數,每條照片發佈數等)咱們使用Pingdom做爲外部監控服務,PagerDuty 用於處理通知和事件。

對於Python錯誤報告,咱們使用Sentry,它是由Disqus的工程師們寫的,是一個極好的開源的Django app。在任什麼時候間,咱們能夠實時的查看系統發生了什麼錯誤。

是你嗎?

若是你對咱們系統的這篇描述感興趣,或者你正躍躍欲試的想告訴咱們關於系統你有什麼不一樣的看法,咱們都靜候佳音。We’re looking for a DevOps person to join us and help us tame our EC2 instance herd.

相關文章
相關標籤/搜索