Twilio的經(jīng)驗分享:合理設計的系統(tǒng)可避免“云震”的傷害
原創(chuàng)【51CTO精選譯文】美國時間4月21日凌晨開始,Amazon位于東海岸的某個數(shù)據(jù)中心發(fā)生故障,并直接導致其網(wǎng)絡服務經(jīng)歷了數(shù)次嚴重中斷(51CTO編輯注:本次事件之后被命名為4.21“云震”)。這次停機事故使得互聯(lián)網(wǎng)上的許多主流網(wǎng)站也相繼陷入癱瘓。這些受到影響的知名網(wǎng)站從一方面證明了云服務當前在推動互聯(lián)網(wǎng)整體系統(tǒng)發(fā)展當中所獲得的驚人成功,但也從另一方面昭示了構建云服務時采用穩(wěn)定的分散式設計的重要性。
Twilio是一家提供云計算平臺上通訊服務的公司,提供各種API服務。在本次Amazon服務中斷事故當中,Twilio的API及相關服務并未受到太大的影響。下面,Twilio的CTO Evan Cooke在其團隊官方博客上分享了Twilio采取的“防震”策略。以下為譯文:
我們在日趨成熟并且將Twilio拓展到Amazon網(wǎng)絡服務之上的同時,也嚴格遵循架構設計的原則,以盡量減少偶然發(fā)生的底層基礎設施故障對業(yè)務的影響。
將故障范圍控制于單獨的主機之中
如果有可能,選擇一些服務項目以及基礎設施來模擬主機發(fā)生故障時的狀況。通過建立一套簡單的單主機服務系統(tǒng)(而不是引入多臺主機),我們就可以構建出不受其它主機工作狀態(tài)影響的獨立服務供應體系。
例如,如果我們的某個應用程序包含A,B,C三種業(yè)務邏輯組成部分,那么每一部分都要運行于獨立的主機之上。我們當然可以將服務群組設置為(A,B,C),(A,B,C)……或者我們也可以創(chuàng)建一套組件池(A,A,…),(B,B,…),(C,C,…)。如果我們選擇了前一種方案,那么單個主機發(fā)生故障將會使整套系統(tǒng)群組遭到破壞。將資源拆開并分配給獨立的池則能夠在單個主機發(fā)生故障時只會對該主機本身的功能性造成影響。我們會在另一篇文章中向大家介紹上述方案的其它優(yōu)勢及存在的缺陷。
極短超時與快速重試
當故障發(fā)生時,我們有相應的軟件快速識別那些失敗及重復提交的請求。通過為每項服務運行多個冗余副本的方式,我們可以使用快速超時及重試來對無法執(zhí)行或連接失敗的服務器進行路由操作。
1. 提出請求,若該請求返回的是一條暫時性錯誤提示或是短時間內(nèi)沒有響應(這個短時間到底有多短,可以根據(jù)大家的應用程序類型而定)
2. 對另一臺服務器重復上述請求
3. 繼續(xù)對另一臺服務器重復上述請求
如果不迅速采取上述措施,分布式系統(tǒng)——尤其是那些按序處理或是基于線程的類型——很有可能會把運算資源浪費在等待緩慢甚至完全無響應的服務器上。
冪等服務接口
構建服務器要求能夠安全地對某項請求進行重復操作。如果大家對“冪等”這個概念不太熟悉,可以先讀讀“冪等領域的精彩世界”一文。
“在計算機科學當中,冪等這個術語被用來全面地形容一種在執(zhí)行了一次或是多次的情況下始終產(chǎn)生相同結果的操作。”
如果某臺服務器的API符合冪等定義,那就意味著其在失敗請求進行重試的過程中是安全的(即我們在前文第2條中所描述的內(nèi)容)。例如,如果某臺服務器提供這樣一種功能,將指定數(shù)目的資金匯入另一位用戶的賬號當中,那么具備冪等接口也就意味著該項請求若是提交失敗,則無論重復提交多少次,都不會造成預期之外的負面效果。關于這個話題其實有很多內(nèi)容可談,我們以后會就更多細節(jié)展開深入的討論。
小型無狀態(tài)服務
將邏輯業(yè)務獨立為小型無狀態(tài)服務能夠使其更容易地通過均等的池加以組織。Twilio的基礎設施中包含了許多分別實現(xiàn)API不同功能部分的服務池。例如,當大家在TwiML中使用<Record>指令來進行錄音時,對錄制內(nèi)容進行后期處理以改善音質(zhì)并進行上傳存儲的工作是由錄制服務中的某個池來完成的。無狀態(tài)池錄制服務允許上游服務通過不同的錄制服務器對失敗的請求進行重試。此外,錄制服務池的大小在負載進行中也很容易加以調(diào)節(jié)。
放寬對一致性的要求
當對信息的一致性沒有太高要求時,為復制及重復讀取數(shù)據(jù)創(chuàng)建對應的池。大家能在應用程序層面所部署的最重要的方案之一就是將數(shù)據(jù)的讀取與寫入分別處理。例如,如果某個巨大的數(shù)據(jù)池在寫入方面的操作極少,就應該將數(shù)據(jù)的讀取與寫入分別進行處理。通過這種區(qū)分,對應的池就能夠獨立創(chuàng)建一套可供服務請求重復讀取的數(shù)據(jù)副本。例如,當服務器整體的數(shù)據(jù)寫入表現(xiàn)良好而數(shù)據(jù)讀取表現(xiàn)較差時,我們可以通過增加讀取服務池的數(shù)量來改善接收及運行讀取請求的效果。
AWS的事故說明我們需要認真反思一下自己云托管應用程序的設計是否合理。我們已經(jīng)著重強調(diào)了幾種知名的分布式系統(tǒng)設計的亮點,而當我們決定將其作為外部服務整合進Twilio之后,它們也確實在工作中起到了良好的作用。
AWS事故的關鍵癥結在于Amazon彈性模塊存儲(簡稱EBS)服務。我們在Twilio中使用了EBS方案,但只應用于那些不太重要且對延遲不太敏感的任務上。我們在將EBS引入自己設施的核心部分方面一直有所保留,因為它不符合我們所追求的“局部故障只影響某臺單獨的主機”這一原則。如果EBS一旦發(fā)生問題,所有相關的服務也很可能同時陷入癱瘓。相反,我們一直堅持在每臺EC2主機上都部署額外的臨時硬盤。如果某塊臨時硬盤出了問題,該問題也只會影響硬盤所在的主機。我還計劃向大家介紹如何將臨時硬盤構建為RAID0以提高讀寫性能,感興趣的朋友們可以繼續(xù)關注我們的博客。
原文:Why Twilio Wasn’t Affected by Today’s AWS Issues
【編輯推薦】