Instagram成功背后的工程技術秘密
Instagram是許多創業公司的楷模,十幾個人的公司,從剛開始的默默無聞到***被Facebook重金收購。這么一家公司,從最開始的操作系統選擇,服務器到數據庫選擇,消息推送,都是如何進行的?本文編譯自Instagram工程博客,告訴你Instagram的技術“秘密”。 在選擇一個系統的時候,我們的核心原則就是:盡量簡單;不做重復工作;盡量采用經過驗證的靠譜的技術。
操作系統/托管
因為當時我們只有三個人,而且需求也不是很多,還沒有到自己建立服務器的地步,所以考慮托管,采用的是 Amazon EC2上的Ubuntu Linux 11.04 (Natty Narwhal )系統,以前版本的Ubuntu在EC2上面跑的時候如果遇到高流量會莫名其妙地死機,但是Natty(Ubuntu的一個版本代號)就沒問題,可能隨著應用發展以及使用的增加,我們會建立自己的服務器。
負載平衡
每個發送到Insagram的請求都要通過負載平衡器,當時我們用2臺 nginx服務器以及DNS輪叫調度承載前端請求,這種方法的負面影響就是,如果一臺機器癱瘓,DNS就得花時間進行更新,于是最近我們使用亞馬遜的彈性負載均衡器(Elastic Load Balancer),我們也在ELB曾停掉了SSL,減小NGINX上CPU壓力,DNS服務則使用亞馬遜的Route53,最近AWS提供了非常不錯的GUI工具。
應用服務器
接下來就是請求的處理,啟用的是亞馬遜 High-CPU Extra-Large 中的Django框架,隨著使用的增加,Diango數量從最開始的幾個增加到超過25個。同時我們采用 http://gunicorn.org/ 作為WSGI服務器,通常我們都習慣使用 mod_wsgi 和Apache,后來發現Gunicorn更容易配置,而且是CPU密集型,如果要同時運行多個實例指令,我們就采用 Fabric(最近增添了幾個有用的平行模式)。
數據儲存
我們的大多數數據(用戶信息,照,標簽等等)都存在 PostgreSQL中,我們曾寫過關于如何在不同 Postgres實例之間共享,我們的主要共享集群包含12個 Quadruple Extra-Large內存實例。
我們發現亞馬遜的網絡磁盤系統(EBS)的每秒尋道能力不足,所以就將數據盡量保存到內存中,為了達到合理的IO性能,我們在使用Mdadm工具的RAID軟件中啟用EBS驅動。
后來發現 vmtouch這種內存數據管理軟件很好用,尤其是在將故障從一臺設備轉到另一臺機器時候,表現很不錯,這是我們我們對vmtouch運行的分析腳本,以及為了與現在的內存狀態相匹配而對應的vmtouch輸出指令,
為了將數據庫與我們的應用服務器相連,我們采用 Pgbouncer,照片本身會直接分享到亞馬遜的S3,利用亞馬遜的CloudFront 作為我們的CDN以節省圖片載入時間。
另外,我們還使用Redis,但由于所有Redis數據都需要與內存匹配,所以我們就停止運行一些Quadruple Extra-Large Memory案例,只在一些特定的子系統中分享一些Redis實例。
對于我們的 geo-search API,已經使用PostgreSQL 幾個月了,不過如果分享了媒體入口,就會使用 Apache Solr,我們這個API還有一個非常簡單的JSON接口,對于我們的應用來說,這相當于另一個API。
***,和任何現代Web服務一樣,我們使用 Memcached 來進行緩存,現在我們有6個 Memcached實例,然后用pylibmc & libmemcached進行連接(亞馬遜最近還推出了一個Elastic Cache)。
任務隊列/消息推送
當有用戶將Insagram圖片分享到Twitter或者Facebook的時候,或者當我們想要知道用戶何時上傳圖片的時候,我們就用Danga開發的任務隊列系統German來處理,這樣一來,不用同時處理任務隊列,上傳媒體文件就非常快。
關于消息推送,我們找到的最節約成本的方案就是https://github.com/samuraisam/pyapns,這是一個開源服務,能為我們處理幾十億消息推送,絕對靠譜。
監控
前面的服務器實例加起來差不多有100多個,所以有效監控實例非常重要,我們用 Munin監控我們整個系統,系統任何異常就及時提醒我們。我們也基于Python-Munin寫了不少定制插件來檢測一些非系統及的特征(比如每秒注冊數量,每秒圖片上傳數量等),同時利用Pingdom 作為服務器外部監控工具,并利用PagerDuty作為消息通知以及突發事件處理工具。
對于Python錯誤報告,使用開源的DIango應用Sentry來處理,可以在任何時候登陸并實時查看系統中出現了哪些錯誤。
【編輯推薦】