在2013年,約莫是我們插手Facebook一周年后,每個月有2億人利用Instagram并且我們存儲了200億照片。絕不躊躇的,我們開始了“Instagration”——從AWS處事器移動到Facebook的基本架構。
兩年后,Instagram已經生長為月活4億有400億照片和視頻的社區,每秒處事高出100萬請求。為了保持對這種增長的支持和確保社區在Instagram上有一個靠得住的體驗,我們抉擇在地理上擴展我們的基本架構。
本文將接頭為什么我們要將基本架構從一個數據中心擴展到三個,和在擴展中碰著的一些技能挑戰。
念頭
Mike Krieger, Instagram的連系首創人和CTO,近期寫了一篇文章,文章中提到了一個故事,約莫在2012年的時候,弗吉尼亞州的一場颶風癱瘓了快要一半的(處事器)實例。
在接下來的36小時里,這個小團隊重建了險些我們全部的基本架構,這種體驗是他們永遠不想反復的。
像這樣的自然災害有大概對數據中心造成姑且的和永久的傷害——我們需要擔保在用戶體驗上有最小的損失。
其他的在地理上擴容的念頭包羅:
區域妨礙的規復: 比自然災害越發常見的是網絡短線、電力問題,等等。譬喻在我們擴展我們的處事到俄勒岡州不久,我們的一個基本構件,包羅memecache和異步層處事器,被關機了,導致了用戶請求的大局限一場。
在我們的新架構下,我們可以或許將流量從該區域轉移走,以減輕我們在從電力妨礙中規復時的問題。
彈性容量擴展: Facebook有不少數據中心。當我們的基本架構籌備好擴展到一個區域甚至當網絡上有不小的延遲時,可以很是容易的將Instagram的容量擴展到所有可用的容量中。這輔佐我們快速抉擇為用戶籌備好新的成果而不消Scramble for基本架構資源來支持他們。
從一到二
所以我們怎么開始這件工作的? 首先讓我們來看一下Instagram的整體基本架構棧。
擴展到大都據中心的要害是區分全局數據和局部數據。全局數據需要在差異的數據中心間復制,而局部數據在每個區域大概差異(譬喻web處事器建設的異步任務應該只在地址的區域被看到)。
下一個要思量的是硬件資源。這個可以大致的氣氛三中:存儲,計較緩和存。
存儲
Instagram主要是用兩種后端數據庫系統:PostgreSQL和Cassandra。他們都有成熟的復制框架來很好的作為全局的一致數據存儲。
全局數據整齊地映射到這些處事器上存儲的數據。方針是在差異的數據中心間保持這些數據的最終一致性,每一個區域有一個讀復制,來制止web處事器的跨數據中心讀。
可是,對PostgreSQL的寫入仍然夸數據中心,因為他們老是要寫到主處事集群上。
CPU處理懲罰
Web處事器,異步處事器都是無狀態的容易漫衍的計較資源,而且只需要會見當地數據。Web處事器可以建設異步事情,這些異步事情被異步動靜署理插手行列,然后被異步處事器消費,全都在一個區域。
緩存
緩存層是web處事器最常會見的層,而且它們需要在同一個數據中心中來制止用戶請求的延遲。這意味著對一個數據中心緩存的更新不會反應到另一個數據中心中,因此對遷移到大都據中心建設了一個挑戰。
想象一個用戶在你的最新頒發的照片上評論。在一個數據中心的環境下,處事這個請求的web處事器可以僅僅在緩存中更新這個新評論。一個存眷者會從同一個緩存中看到這個新評論。
然而在大都據中心的情景下,假如評論者和存眷者被差異的區域處事,存眷者的區域緩存將不會被更新,這個用戶就不能看到評論。
我們的辦理要領是利用PgQ, 加強它使得插入緩存失效事件到被修改的數據庫中。
在主節點:
Web處事器插入一條評論到PostgreSQL數據庫中 Web處事器在同一個數據庫中插入一個緩存失效條目
在從節點:
復制主數據庫,包羅新插入的評論緩和存失效條目 緩存失效處理懲罰讀取緩存失效條目而且使區域緩存失效 Django集群從數據庫中讀到新插入的評論而且從頭填充緩存
這辦理了緩存一致性問題。另一方面,相對付單區域的例子,django處事器直接更新緩存而不從頭讀區數據庫,多區域時會增加數據庫的讀負載。
為了減輕這個問題,我們利用了兩種步伐:1) 通過冗余計數器淘汰每一個讀需要的計較資源;2) 通過緩存租約淘汰讀的數量。
冗余計數器
最常見的緩存鍵是計數器。譬喻,我們利用一個計數器來確定喜歡Justin Bieber的一個詳細的帖子的人數。
當只有一個區域時,我們可以從web處事器增加memcache的計數器,所以制止一個“select count(*)”的數據庫挪用,這回節減幾百毫秒。
可是在有兩個區域和PgQ失效時,每一個新的喜歡對計數器建設了一個緩存失效事件。這會建設大量的“select count(*)”,尤其是在熱點工具上。