我們生活在一個(gè)時(shí)代,大規(guī)模的,面向互聯(lián)網(wǎng)的系統(tǒng)(例如Google,Amazon,F(xiàn)acebook等)是工程界的偶像。 他們每秒處理大量請(qǐng)求,并管理規(guī)??涨暗臄?shù)據(jù)存儲(chǔ)庫(kù)。 出于商業(yè)秘密的原因,在這些系統(tǒng)上獲取準(zhǔn)確的流量數(shù)字并不容易。 但是,這些站點(diǎn)隨著使用量的增長(zhǎng)而迅速擴(kuò)展的能力是其持續(xù)成功的關(guān)鍵因素。
幸運(yùn)的是,我們可以通過(guò)一家技術(shù)公司的年度使用情況報(bào)告深入了解以Internet規(guī)模處理的請(qǐng)求和數(shù)據(jù)量。 從2019年起,您可以在此瀏覽其令人難以置信的詳細(xì)使用情況統(tǒng)計(jì)信息。這是對(duì)大規(guī)模系統(tǒng)功能的令人著迷的一瞥。 不過(guò)請(qǐng)注意,這是Pornhub.com。 該報(bào)告不適合該報(bào)告。 以下是PG-13的一個(gè)示例性數(shù)據(jù)點(diǎn)-他們?cè)?019年有420億的訪(fǎng)問(wèn)量!
對(duì)于絕大多數(shù)企業(yè)和政府系統(tǒng)而言,可擴(kuò)展性并不是開(kāi)發(fā)和部署初期的主要質(zhì)量要求。 增強(qiáng)可用性和實(shí)用性的新功能是我們開(kāi)發(fā)周期的驅(qū)動(dòng)力。 只要正常負(fù)載下的性能足夠,我們就會(huì)繼續(xù)添加面向用戶(hù)的功能,以提高系統(tǒng)的業(yè)務(wù)價(jià)值。
盡管如此,系統(tǒng)發(fā)展成為一種狀態(tài),在這種狀態(tài)下,增強(qiáng)的性能和可伸縮性變得迫在眉睫,甚至是生存,這并不少見(jiàn)。 引人注目的功能和高實(shí)用性催生了成功,這帶來(lái)了更多的處理請(qǐng)求和更多的數(shù)據(jù)管理。 這通常預(yù)示著一個(gè)臨界點(diǎn),在輕載下有意義的設(shè)計(jì)決策現(xiàn)在突然變成了技術(shù)負(fù)擔(dān)。 外部觸發(fā)事件通常會(huì)導(dǎo)致這些轉(zhuǎn)折點(diǎn)-在2020年3月的媒體上,許多報(bào)道稱(chēng)政府失業(yè)和超市在線(xiàn)訂購(gòu)網(wǎng)站由于冠狀病毒大流行而在需求下崩潰。
當(dāng)達(dá)到這個(gè)臨界點(diǎn)時(shí),架構(gòu)師有責(zé)任帶領(lǐng)系統(tǒng)演進(jìn)為高響應(yīng),可擴(kuò)展的系統(tǒng)。 核心系統(tǒng)的架構(gòu)機(jī)制和模式將需要重新設(shè)計(jì),以使其能夠應(yīng)對(duì)不斷增長(zhǎng)的需求。 對(duì)于許多架構(gòu)師而言,這是未知的或陌生的領(lǐng)域,因?yàn)榭缮炜s性使我們走下了有時(shí)對(duì)于廣泛理解的軟件體系結(jié)構(gòu)原理而言異端的道路。
以下六個(gè)經(jīng)驗(yàn)法則代表著每位軟件架構(gòu)師必須幫助他們構(gòu)建可伸縮系統(tǒng)的知識(shí)。 這些通用規(guī)則可以為架構(gòu)師在可靠地處理不斷增長(zhǎng)的請(qǐng)求負(fù)載和數(shù)據(jù)量的過(guò)程中提供指導(dǎo)。
成本和可擴(kuò)展性有著不可磨滅的聯(lián)系
擴(kuò)展系統(tǒng)的核心原則是能夠輕松添加新的處理資源來(lái)處理增加的負(fù)載。 對(duì)于許多系統(tǒng),一種簡(jiǎn)單有效的方法是部署多個(gè)無(wú)狀態(tài)服務(wù)器資源實(shí)例,并使用負(fù)載平衡器在這些實(shí)例之間分配請(qǐng)求(請(qǐng)參見(jiàn)圖1)。 假設(shè)將這些資源部署在Amazon Web Services之類(lèi)的云平臺(tái)上,則基本費(fèi)用為:
· 每個(gè)服務(wù)器實(shí)例的虛擬機(jī)部署成本
· 負(fù)載均衡器的成本,取決于新請(qǐng)求和活動(dòng)請(qǐng)求的數(shù)量以及處理的數(shù)據(jù)量
在這種情況下,隨著請(qǐng)求負(fù)載的增長(zhǎng),就需要運(yùn)行服務(wù)器代碼的已部署虛擬機(jī)具有更大的處理能力。 這導(dǎo)致更高的成本。 您的負(fù)載均衡器成本還將與您的請(qǐng)求負(fù)載和數(shù)據(jù)大小成比例地增長(zhǎng)。
> Figure 1 A Simple Load Balancing Example
因此,成本和規(guī)模是并存的。 您關(guān)于可伸縮性的設(shè)計(jì)決策不可避免地會(huì)影響您的部署成本。 忘記了這一點(diǎn),您可能會(huì)發(fā)現(xiàn)自己以及許多知名公司在一個(gè)月底收到了意外大筆的部署費(fèi)用!
在這種情況下,您的設(shè)計(jì)如何降低成本? 主要有兩種方法:
· 使用彈性負(fù)載平衡器可根據(jù)瞬時(shí)請(qǐng)求負(fù)載來(lái)調(diào)整服務(wù)器實(shí)例的數(shù)量。 然后,在交通繁忙期間,您需要為最少數(shù)量的服務(wù)器實(shí)例付費(fèi)。 隨著請(qǐng)求量的增長(zhǎng),負(fù)載均衡器會(huì)產(chǎn)生新的實(shí)例,并且容量也會(huì)相應(yīng)地增長(zhǎng)。
· 增加每個(gè)服務(wù)器實(shí)例的容量。 這通常是通過(guò)調(diào)整服務(wù)器部署參數(shù)(例如線(xiàn)程數(shù),連接數(shù),堆大小等)來(lái)完成的。 默認(rèn)平臺(tái)設(shè)置很少適合您的工作負(fù)載。 仔細(xì)選擇參數(shù)設(shè)置可以顯著提高性能,從而提高容量。 您基本上是在使用相同的資源來(lái)完成更多工作-這是實(shí)現(xiàn)擴(kuò)展的關(guān)鍵原則。
您的系統(tǒng)存在瓶頸。 某處!
擴(kuò)展系統(tǒng)實(shí)質(zhì)上意味著增加其容量。 在上面的示例中,我們通過(guò)在負(fù)載平衡的計(jì)算資源上部署更多服務(wù)器實(shí)例來(lái)提高請(qǐng)求處理能力。 但是,軟件系統(tǒng)包括多個(gè)從屬處理元素或微服務(wù)。 不可避免地,隨著某些微服務(wù)中容量的增加,您將淹沒(méi)其他微服務(wù)中的容量。
在我們的負(fù)載均衡示例中,假設(shè)我們的服務(wù)器實(shí)例均具有到同一共享數(shù)據(jù)庫(kù)的連接。 隨著部署服務(wù)器數(shù)量的增加,我們?cè)黾恿藬?shù)據(jù)庫(kù)上的請(qǐng)求負(fù)載(請(qǐng)參見(jiàn)圖2)。 在某個(gè)階段,此數(shù)據(jù)庫(kù)將達(dá)到飽和,并且數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)將開(kāi)始引起更多的延遲。 現(xiàn)在,您的數(shù)據(jù)庫(kù)已成為瓶頸,無(wú)論您增加更多的服務(wù)器處理能力都無(wú)所謂。 為了進(jìn)一步擴(kuò)展,解決方案是以某種方式增加數(shù)據(jù)庫(kù)容量。 您可以嘗試優(yōu)化查詢(xún),或添加更多的CPU和/或內(nèi)存。 也許復(fù)制和/或分片數(shù)據(jù)庫(kù)。 有很多可能性。
> Figure 2 Increasing Server Capacity creates a Bottleneck at the Database
系統(tǒng)中的任何共享資源都可能成為限制容量的瓶頸。 當(dāng)您增加部分架構(gòu)的容量時(shí),您需要仔細(xì)查看下游的容量,以確保不會(huì)因請(qǐng)求突然而意外地淹沒(méi)您的系統(tǒng)。 這會(huì)迅速導(dǎo)致級(jí)聯(lián)故障(請(qǐng)參閱下一條規(guī)則),并使整個(gè)系統(tǒng)崩潰。
數(shù)據(jù)庫(kù),消息隊(duì)列,長(zhǎng)時(shí)間等待的網(wǎng)絡(luò)連接,線(xiàn)程和連接池以及共享的微服務(wù)都是瓶頸的主要候選者。 您可以放心,高流量負(fù)載將迅速暴露這些元素。 關(guān)鍵是防止瓶頸暴露時(shí)突然崩潰,并能夠快速部署更多容量。
慢服務(wù)比失敗服務(wù)更邪惡
在正常操作下,系統(tǒng)應(yīng)設(shè)計(jì)為在微服務(wù)和組成系統(tǒng)的數(shù)據(jù)庫(kù)之間提供穩(wěn)定,低延遲的通信。 盡管系統(tǒng)負(fù)載保持在您設(shè)計(jì)的運(yùn)行配置文件之內(nèi),但性能仍然是可預(yù)測(cè)的,一致且快速的,如圖3所示。
> Figure 3 Low latencies under normal load
隨著客戶(hù)端負(fù)載增加到超出操作配置文件的范圍,微服務(wù)之間的請(qǐng)求等待時(shí)間將開(kāi)始增加。 首先,這通常是一個(gè)緩慢而穩(wěn)定的增長(zhǎng),可能不會(huì)嚴(yán)重影響整個(gè)系統(tǒng)的運(yùn)行,尤其是在負(fù)載激增短暫的情況下。 但是,如果傳入請(qǐng)求負(fù)載繼續(xù)超過(guò)容量(服務(wù)B),則未完成的請(qǐng)求將開(kāi)始備份在發(fā)出請(qǐng)求的微服務(wù)(服務(wù)A)中,由于下游等待時(shí)間較慢,該服務(wù)現(xiàn)在看到的傳入請(qǐng)求多于已完成的請(qǐng)求。 如圖4所示。
> Figure 4 Increased load causes longer latencies and requests to back up
在這種情況下,事情可能真的會(huì)迅速消退。 當(dāng)一項(xiàng)服務(wù)不堪重負(fù),并且由于顛簸或資源耗盡而基本停止運(yùn)行時(shí),請(qǐng)求的服務(wù)將無(wú)法響應(yīng)其客戶(hù),而客戶(hù)也將停止運(yùn)行。 導(dǎo)致的結(jié)果稱(chēng)為級(jí)聯(lián)故障-緩慢的微服務(wù)導(dǎo)致請(qǐng)求沿著請(qǐng)求處理路徑建立,直到整個(gè)系統(tǒng)突然出現(xiàn)故障。
這就是為什么緩慢的服務(wù)是邪惡的,而不是不可用的服務(wù)更是如此。 如果您呼叫失敗的服務(wù)或由于瞬態(tài)網(wǎng)絡(luò)問(wèn)題而進(jìn)行了分區(qū)的服務(wù),則您會(huì)立即收到異常消息,并可以明智地決定做什么(例如退避并重試,報(bào)告錯(cuò)誤)。 逐漸不堪重負(fù)的服務(wù)正常運(yùn)行,只是延遲時(shí)間更長(zhǎng)。 這暴露了所有依賴(lài)服務(wù)中的潛在瓶頸,最終,出了一些大問(wèn)題。
斷路器和隔板等架構(gòu)模式可防止級(jí)聯(lián)故障。 如果對(duì)服務(wù)的延遲超過(guò)指定值,則斷路器可以限制請(qǐng)求負(fù)載或釋放請(qǐng)求負(fù)載。 如果只有一個(gè)下游服務(wù)依賴(lài)項(xiàng)失敗,則隔板可以保護(hù)整個(gè)微服務(wù)免于失敗。 使用它們來(lái)構(gòu)建彈性以及高度可擴(kuò)展的體系結(jié)構(gòu)。
數(shù)據(jù)層最難擴(kuò)展
核心業(yè)務(wù)數(shù)據(jù)示例是客戶(hù)資料,交易和帳戶(hù)余額。 這些必須正確,一致且可用。
操作數(shù)據(jù)示例包括用戶(hù)會(huì)話(huà)時(shí)長(zhǎng),每小時(shí)訪(fǎng)問(wèn)者和頁(yè)面瀏覽量。 該數(shù)據(jù)通常具有保存期限,并且可以隨時(shí)間進(jìn)行匯總和匯總。 如果還不是100%完成,那就不是世界末日。 因此,我們可以更輕松地捕獲和存儲(chǔ)帶外操作數(shù)據(jù),例如將其寫(xiě)入日志文件或消息隊(duì)列。 消費(fèi)者然后定期檢索數(shù)據(jù)并將其寫(xiě)入數(shù)據(jù)存儲(chǔ)。
隨著系統(tǒng)請(qǐng)求處理層的擴(kuò)展,共享事務(wù)數(shù)據(jù)庫(kù)將承受更多負(fù)載。 隨著查詢(xún)負(fù)載的增加,這些可能迅速成為瓶頸。 查詢(xún)優(yōu)化是一個(gè)有用的第一步,添加更多內(nèi)存以使數(shù)據(jù)庫(kù)引擎能夠緩存索引和表數(shù)據(jù)也是如此。 最終,您的數(shù)據(jù)庫(kù)引擎將耗盡所有精力,并且需要進(jìn)行更根本的更改。
首先要注意的是,任何數(shù)據(jù)組織的更改都可能在數(shù)據(jù)層帶來(lái)痛苦。 如果更改關(guān)系數(shù)據(jù)庫(kù)中的架構(gòu),則可能必須運(yùn)行腳本以重新加載數(shù)據(jù)以匹配新架構(gòu)。 在腳本運(yùn)行期間(對(duì)于大型數(shù)據(jù)庫(kù)而言可能是很長(zhǎng)的時(shí)間),系統(tǒng)無(wú)法進(jìn)行寫(xiě)入。 這可能不會(huì)使您的客戶(hù)滿(mǎn)意。
NoSQL,無(wú)模式數(shù)據(jù)庫(kù)減輕了重新加載數(shù)據(jù)庫(kù)的需要,但是您仍然必須更改查詢(xún)級(jí)代碼才能識(shí)別已修改的數(shù)據(jù)組織。 如果您擁有業(yè)務(wù)數(shù)據(jù)集合,其中某些項(xiàng)目的格式已修改,而某些項(xiàng)目的原始格式已修改,則可能還需要管理數(shù)據(jù)對(duì)象的版本控制。
進(jìn)一步擴(kuò)展可能需要分發(fā)數(shù)據(jù)庫(kù)。 帶有只讀副本的領(lǐng)導(dǎo)者追隨者模型可能就足夠了。 對(duì)于大多數(shù)數(shù)據(jù)庫(kù)來(lái)說(shuō),這很容易設(shè)置,但是需要密切的持續(xù)監(jiān)視。 領(lǐng)導(dǎo)者死亡時(shí),故障轉(zhuǎn)移很少是瞬時(shí)的,有時(shí)需要手動(dòng)干預(yù)。 這些問(wèn)題都是非常依賴(lài)數(shù)據(jù)庫(kù)引擎的。
如果采用無(wú)領(lǐng)導(dǎo)者方法,則必須決定如何最好地在多個(gè)節(jié)點(diǎn)之間分配和分區(qū)數(shù)據(jù)。 在大多數(shù)數(shù)據(jù)庫(kù)中,一旦選擇了分區(qū)鍵,就無(wú)法在不重建數(shù)據(jù)庫(kù)的情況下進(jìn)行更改。 不用說(shuō),分區(qū)鍵需要明智地選擇! 分區(qū)鍵還控制如何在節(jié)點(diǎn)之間分配數(shù)據(jù)。 隨著添加節(jié)點(diǎn)以提供更大的容量,需要進(jìn)行重新平衡以在新節(jié)點(diǎn)上分布數(shù)據(jù)和請(qǐng)求。 同樣,數(shù)據(jù)庫(kù)文檔的內(nèi)容中描述了它的工作方式。 有時(shí)它并不像它可能的那樣平滑。
由于分布式數(shù)據(jù)庫(kù)的潛在管理難題,基于托管的基于云的替代方案(例如AWS Dynamodb,Google Firestore)通常是首選。 當(dāng)然,需要權(quán)衡取舍-這是另一個(gè)故事的主題!
這里的信息很簡(jiǎn)單。 更改邏輯和物理數(shù)據(jù)模型以擴(kuò)展查詢(xún)處理能力很少是一個(gè)平穩(wěn)而簡(jiǎn)單的過(guò)程。 想要不經(jīng)常面對(duì)的人。
快取! 快取! 并緩存更多!
減輕數(shù)據(jù)庫(kù)負(fù)載的一種方法是避免盡可能訪(fǎng)問(wèn)它。 這就是緩存的用處。您友好的數(shù)據(jù)庫(kù)引擎應(yīng)該能夠充分利用節(jié)點(diǎn)緩存上的資源。 這是一個(gè)簡(jiǎn)單且有用的解決方案,如果可能會(huì)很昂貴。
更好的是,如果不需要,為什么還要查詢(xún)數(shù)據(jù)庫(kù)? 對(duì)于經(jīng)常讀取且很少更改的數(shù)據(jù),可以修改您的處理邏輯以首先檢查分布式緩存,例如memcached服務(wù)器。 這需要遠(yuǎn)程調(diào)用,但是如果您需要的數(shù)據(jù)在高速緩存中,則在快速網(wǎng)絡(luò)上,這比查詢(xún)數(shù)據(jù)庫(kù)實(shí)例要便宜得多。
引入緩存層需要修改您的處理邏輯,以檢查緩存數(shù)據(jù)。 如果所需的內(nèi)容不在高速緩存中,則您的代碼仍必須查詢(xún)數(shù)據(jù)庫(kù),然后將結(jié)果加載到高速緩存中并將其返回給調(diào)用方。 您還需要決定何時(shí)刪除或使緩存的結(jié)果無(wú)效-這取決于您的應(yīng)用程序向客戶(hù)提供陳舊結(jié)果的容忍度。
設(shè)計(jì)良好的緩存方案對(duì)于擴(kuò)展系統(tǒng)絕對(duì)是無(wú)價(jià)的。 如果您可以處理來(lái)自緩存的大部分讀取請(qǐng)求,則可以在數(shù)據(jù)庫(kù)上購(gòu)買(mǎi)額外的容量,因?yàn)樗鼈儾粎⑴c處理大多數(shù)請(qǐng)求。 這意味著您可以避免復(fù)雜且痛苦的數(shù)據(jù)層修改(請(qǐng)參閱上一條規(guī)則),同時(shí)為越來(lái)越多的請(qǐng)求創(chuàng)建容量。 這是使大家開(kāi)心的秘訣! 甚至?xí)?jì)師。
監(jiān)控是可伸縮系統(tǒng)的基礎(chǔ)
這是很多工作。 而且很難使所有事物都代表現(xiàn)實(shí),因此您可以獲得有意義的結(jié)果。 毫不奇怪,它很少完成。
替代方法是監(jiān)視。 對(duì)系統(tǒng)的簡(jiǎn)單監(jiān)視涉及確?;A(chǔ)結(jié)構(gòu)正常運(yùn)行。 如果資源不足,例如內(nèi)存或磁盤(pán)空間不足,或者遠(yuǎn)程調(diào)用失敗,則應(yīng)向您發(fā)出警報(bào),以便在真正的不良情況發(fā)生之前可以采取補(bǔ)救措施。
以上監(jiān)視見(jiàn)解是必要的,但不足。 隨著系統(tǒng)的擴(kuò)展,您需要了解應(yīng)用程序行為之間的關(guān)系。 一個(gè)簡(jiǎn)單的示例是,隨著并發(fā)寫(xiě)入請(qǐng)求數(shù)量的增加,數(shù)據(jù)庫(kù)的寫(xiě)入性能如何。 您還想知道何時(shí)由于下游延遲增加而使斷路器在微服務(wù)中跳閘,負(fù)載平衡器何時(shí)開(kāi)始產(chǎn)生新實(shí)例或消息在隊(duì)列中保留的時(shí)間超過(guò)指定的閾值。
有許多可用于監(jiān)視的解決方案。 Splunk是一個(gè)全面而強(qiáng)大的日志聚合框架。 任何云都有其自己的監(jiān)視框架,例如AWS Cloudwatch。 這些功能使您可以捕獲有關(guān)系統(tǒng)行為的指標(biāo),并將其顯示在統(tǒng)一的儀表板中,以支持對(duì)性能的監(jiān)視和分析。 術(shù)語(yǔ)"可觀察性"通常用于涵蓋監(jiān)視和性能分析的整個(gè)過(guò)程。
有兩件事(至少?。┮紤]。
首先,要獲得對(duì)性能的深入了解,您將需要生成與應(yīng)用程序行為細(xì)節(jié)相關(guān)的自定義指標(biāo)。 仔細(xì)設(shè)計(jì)這些指標(biāo),并在您的微服務(wù)中添加代碼以將其注入到您的監(jiān)視框架中,以便可以在系統(tǒng)儀表板中對(duì)其進(jìn)行觀察和分析。
其次,監(jiān)視是系統(tǒng)中的必要功能(和成本)。 它已打開(kāi)。 總是。 當(dāng)您需要調(diào)整性能和擴(kuò)展系統(tǒng)時(shí),捕獲的數(shù)據(jù)將指導(dǎo)您的實(shí)驗(yàn)和工作。 在系統(tǒng)演進(jìn)中以數(shù)據(jù)為驅(qū)動(dòng)力有助于確保您花費(fèi)時(shí)間修改和改進(jìn)系統(tǒng)部分,這些部分對(duì)于支持性能和擴(kuò)展要求至關(guān)重要。
結(jié)論
高性能和可伸縮性通常不是我們構(gòu)建的許多系統(tǒng)的優(yōu)先質(zhì)量要求。 通常,了解,實(shí)施和發(fā)展功能需求是很成問(wèn)題的,以致浪費(fèi)所有可用的時(shí)間和預(yù)算。 但是有時(shí),在外部事件或意外成功的驅(qū)動(dòng)下,可伸縮性是必要的,否則您的系統(tǒng)將因負(fù)載不足而崩潰。 不可用的系統(tǒng)(或由于性能降低而實(shí)際上不可用)對(duì)任何人都沒(méi)有用。
-
互聯(lián)網(wǎng)
+關(guān)注
關(guān)注
54文章
11219瀏覽量
105206 -
軟件架構(gòu)
+關(guān)注
關(guān)注
0文章
64瀏覽量
10441
發(fā)布評(píng)論請(qǐng)先 登錄
函數(shù)指針的六個(gè)常見(jiàn)應(yīng)用場(chǎng)景

AFE5801 fclkin只能輸入只列出了65、50、40、30、20、10MHz這六個(gè)值嗎?
ADS805E的轉(zhuǎn)換結(jié)果要延后六個(gè)采樣周期才輸出嗎?
【「RISC-V體系結(jié)構(gòu)編程與實(shí)踐」閱讀體驗(yàn)】-- SBI及NEMU環(huán)境
【「RISC-V體系結(jié)構(gòu)編程與實(shí)踐」閱讀體驗(yàn)】-- 前言與開(kāi)篇
焊接機(jī)器人六個(gè)軸分別是什么作用

GPGPU體系結(jié)構(gòu)優(yōu)化方向(1)

無(wú)刷DC門(mén)驅(qū)動(dòng)系統(tǒng)的體系結(jié)構(gòu)

名單公布!【書(shū)籍評(píng)測(cè)活動(dòng)NO.45】RISC-V體系結(jié)構(gòu)編程與實(shí)踐(第二版)
嵌入式系統(tǒng)的體系結(jié)構(gòu)包括哪些
DCS的硬件體系結(jié)構(gòu)

評(píng)論