「可擴(kuò)展性」可擴(kuò)展性最佳實(shí)踐:來(lái)自eBay的經(jīng)驗(yàn)教訓(xùn)

來(lái)源: 超級(jí)架構(gòu)師
作者:南極真君
時(shí)間:2021-05-12
17125
在eBay,我們每天都在爭(zhēng)論的主要架構(gòu)力量之一是可擴(kuò)展性。它為我們制定的每一個(gè)架構(gòu)和設(shè)計(jì)決策著色和推動(dòng)。全球有數(shù)億用戶(hù),每天超過(guò)20億的頁(yè)面瀏覽量,以及我們系統(tǒng)中的數(shù)PB數(shù)據(jù),這不是一個(gè)選擇-它是必需的。

pexels-photo-2967810.webp.jpg

在eBay,我們每天都在爭(zhēng)論的主要架構(gòu)力量之一是可擴(kuò)展性。它為我們制定的每一個(gè)架構(gòu)和設(shè)計(jì)決策著色和推動(dòng)。全球有數(shù)億用戶(hù),每天超過(guò)20億的頁(yè)面瀏覽量,以及我們系統(tǒng)中的數(shù)PB數(shù)據(jù),這不是一個(gè)選擇-它是必需的。

在可擴(kuò)展的體系結(jié)構(gòu)中,資源使用應(yīng)該隨負(fù)載線(xiàn)性增加(或更好),其中可以在用戶(hù)流量,數(shù)據(jù)量等中測(cè)量負(fù)載。在性能與單個(gè)工作單元相關(guān)的資源使用情況下,可伸縮性是關(guān)于如何隨著工作單元數(shù)量或大小的增加,資源使用情況發(fā)生變化。換句話(huà)說(shuō),可伸縮性是價(jià)格-性能曲線(xiàn)的形狀,而不是其在該曲線(xiàn)中的一點(diǎn)處的值。

可伸縮性有許多方面-事務(wù)性,操作性,開(kāi)發(fā)性工作。在本文中,我將概述我們隨著時(shí)間的推移學(xué)習(xí)的幾個(gè)關(guān)鍵最佳實(shí)踐,以擴(kuò)展基于Web的系統(tǒng)的事務(wù)吞吐量。大多數(shù)這些最佳實(shí)踐對(duì)您來(lái)說(shuō)都很熟悉。有些人可能沒(méi)有。所有這些都來(lái)自開(kāi)發(fā)和運(yùn)營(yíng)eBay網(wǎng)站的人們的集體經(jīng)驗(yàn)。

最佳實(shí)踐#1:按功能劃分

無(wú)論您將其稱(chēng)為SOA,功能分解還是簡(jiǎn)單的良好工程,相關(guān)的功能都屬于一體,而不相關(guān)的功能則屬于不同。此外,不相關(guān)的功能可以解耦得越多,就越需要彼此獨(dú)立地?cái)U(kuò)展它們。

在代碼級(jí)別,我們都會(huì)一直這樣做。JAR文件,包,包等都是我們用來(lái)隔離和抽象一組功能的機(jī)制。

在應(yīng)用層,eBay將不同的功能劃分為單獨(dú)的應(yīng)用程序池。銷(xiāo)售功能由一組應(yīng)用程序服務(wù)器提供,競(jìng)標(biāo)功能由另一組應(yīng)用程序服務(wù)器提供,另一組應(yīng)用程序服務(wù)器進(jìn)行搜索??偟膩?lái)說(shuō),我們將大約16,000個(gè)應(yīng)用服務(wù)器組織到220個(gè)不同的池中。這允許我們根據(jù)其功能的需求和資源消耗,彼此獨(dú)立地?cái)U(kuò)展每個(gè)池。它進(jìn)一步允許我們隔離和合理化資源依賴(lài)性-例如,銷(xiāo)售池只需要與相對(duì)較小的后端資源子集進(jìn)行通信。

在數(shù)據(jù)庫(kù)層,我們遵循相同的方法。eBay上沒(méi)有單一的整體數(shù)據(jù)庫(kù)。相反,有一組用于用戶(hù)數(shù)據(jù)的數(shù)據(jù)庫(kù)主機(jī),一個(gè)用于項(xiàng)目數(shù)據(jù)的集合,一個(gè)用于購(gòu)買(mǎi)數(shù)據(jù)的集合等。-在400個(gè)物理主機(jī)上共有1000個(gè)邏輯數(shù)據(jù)庫(kù)。同樣,這種方法允許我們?yōu)槊糠N類(lèi)型的數(shù)據(jù)獨(dú)立地?cái)U(kuò)展數(shù)據(jù)庫(kù)基礎(chǔ)結(jié)構(gòu)。

最佳實(shí)踐#2:水平分割

雖然功能分區(qū)使我們成為一種方式,但對(duì)于完全可擴(kuò)展的架構(gòu)而言,它本身并不足夠。由于一個(gè)功能可能與另一個(gè)功能分離,因此單個(gè)功能區(qū)域的需求可能并且將隨著時(shí)間的推移而超過(guò)任何單個(gè)系統(tǒng)?;蛘?,正如我們想提醒自己的那樣,“如果你不能拆分它,你就無(wú)法擴(kuò)展它?!币虼?,在特定的功能區(qū)域內(nèi),我們需要能夠?qū)⒐ぷ髁糠纸鉃榭晒芾淼膯卧?,其中每個(gè)單元保持良好的性?xún)r(jià)比。這是水平分割的來(lái)源。

在應(yīng)用層,eBay的交互是設(shè)計(jì)無(wú)狀態(tài)的,水平分割是微不足道的。使用標(biāo)準(zhǔn)負(fù)載平衡器來(lái)路由傳入流量。因?yàn)樗袘?yīng)用程序服務(wù)器都是相同的,并且沒(méi)有保留任何事務(wù)狀態(tài),所以它們中的任何一個(gè)都可以。如果我們需要更多處理能力,我們只需添加更多應(yīng)用服務(wù)器。

數(shù)據(jù)庫(kù)層出現(xiàn)了更具挑戰(zhàn)性的問(wèn)題,因?yàn)楦鶕?jù)定義數(shù)據(jù)是有狀態(tài)的。在這里,我們沿著主要訪(fǎng)問(wèn)路徑水平分割(或“分片”)數(shù)據(jù)。例如,用戶(hù)數(shù)據(jù)當(dāng)前分為20個(gè)主機(jī),每個(gè)主機(jī)包含1/20的用戶(hù)。隨著用戶(hù)數(shù)量的增長(zhǎng),以及我們?yōu)槊總€(gè)用戶(hù)存儲(chǔ)的數(shù)據(jù)增長(zhǎng),我們會(huì)添加更多主機(jī),并進(jìn)一步細(xì)分用戶(hù)。同樣,我們對(duì)項(xiàng)目,購(gòu)買(mǎi),帳戶(hù)等使用相同的方法。不同的用例使用不同的方案來(lái)劃分?jǐn)?shù)據(jù):一些基于密鑰的簡(jiǎn)單模數(shù)(以1結(jié)尾的項(xiàng)目ID轉(zhuǎn)到一個(gè)主機(jī),以2結(jié)尾的那些等等,其中一些在一系列ID(0-1M,1-2M等)上,一些在查找表上,一些在這些策略的組合上。然而,無(wú)論分區(qū)方案的細(xì)節(jié)如何,一般的想法是支持?jǐn)?shù)據(jù)分區(qū)和重新分區(qū)的基礎(chǔ)設(shè)施將比不支持分區(qū)和重新分區(qū)的基礎(chǔ)設(shè)施更具可擴(kuò)展性。

最佳實(shí)踐#3:避免分布式事務(wù)

此時(shí),您可能想知道如何通過(guò)事務(wù)保證在功能和水平方面對(duì)數(shù)據(jù)進(jìn)行分區(qū)。畢竟,幾乎任何有趣的操作都會(huì)更新多種類(lèi)型的實(shí)體-用戶(hù)和物品會(huì)立即浮現(xiàn)在腦海中。正統(tǒng)的答案是眾所周知且易于理解的-使用兩階段提交在各種資源之間創(chuàng)建分布式事務(wù),以保證所有資源的所有更新都發(fā)生或不發(fā)生。不幸的是,這種悲觀的方法帶來(lái)了巨大的成本。協(xié)調(diào)成本會(huì)對(duì)擴(kuò)展,性能和延遲產(chǎn)生負(fù)面影響,隨著您增加依賴(lài)資源和傳入客戶(hù)端的數(shù)量,協(xié)調(diào)成本會(huì)惡化。可用性同樣受限于所有相關(guān)資源可用的要求。務(wù)實(shí)的答案是放寬不相關(guān)系統(tǒng)的交易保證。

事實(shí)證明,你不能擁有一切。特別是,通常既不需要也不可能保證跨多個(gè)系統(tǒng)或分區(qū)的立即一致性。大約10年前由Inktomi的Eric Brewer提出的CAP定理指出,分布式系統(tǒng)的三個(gè)非常理想的特性-一致性(C),可用性(A)和分區(qū)容差(P)-你只能選擇兩個(gè)一度。對(duì)于高流量網(wǎng)站,我們必須選擇分區(qū)容差,因?yàn)樗菙U(kuò)展的基礎(chǔ)。對(duì)于24x7網(wǎng)站,我們通常會(huì)選擇可用性。因此,即時(shí)一致性必須讓位。

在eBay,我們絕對(duì)不允許任何類(lèi)型的客戶(hù)端或分布式事務(wù)-沒(méi)有兩階段提交。在某些明確定義的情況下,我們將單個(gè)數(shù)據(jù)庫(kù)上的多個(gè)語(yǔ)句組合成單個(gè)事務(wù)操作。但是,在大多數(shù)情況下,單個(gè)語(yǔ)句是自動(dòng)提交的。雖然這種對(duì)正統(tǒng)ACID屬性的有意放松并不能保證在任何地方都能立即保持一致,但實(shí)際情況是大多數(shù)系統(tǒng)在絕大多數(shù)情況下都是可用的。當(dāng)然,我們采用各種技術(shù)來(lái)幫助系統(tǒng)達(dá)到最終的一致性:仔細(xì)排序數(shù)據(jù)庫(kù)操作,異步恢復(fù)事件以及協(xié)調(diào)或結(jié)算批次。我們根據(jù)特定用例的一致性要求選擇技術(shù)。

對(duì)于架構(gòu)師和系統(tǒng)設(shè)計(jì)師來(lái)說(shuō),關(guān)鍵的一點(diǎn)是,不應(yīng)將一致性視為一個(gè)全有或全無(wú)的命題。大多數(shù)真實(shí)世界的用例根本不需要立即一致性。正如可用性不是全部或全部,我們經(jīng)常將其與成本和其他力量進(jìn)行權(quán)衡,同樣我們的工作也會(huì)根據(jù)特定操作的要求定制適當(dāng)?shù)囊恢滦员WC。

最佳實(shí)踐#4:異步解耦功能

擴(kuò)展的下一個(gè)關(guān)鍵要素是積極使用異步。如果組件A同步調(diào)用組件B,則A和B緊密耦合,并且該耦合系統(tǒng)具有單一的可伸縮性特征-為了擴(kuò)展A,您還必須擴(kuò)展B.同樣有問(wèn)題的是它對(duì)可用性的影響?;氐竭壿?01,if A implies B,then not-B implies not-A。換句話(huà)說(shuō),如果B下降則A下降。相反,如果A和B異步集成,無(wú)論是通過(guò)隊(duì)列,多播消息傳遞,批處理過(guò)程還是其他方式,每個(gè)都可以獨(dú)立于另一個(gè)進(jìn)行縮放。此外,A和B現(xiàn)在具有獨(dú)立的可用性特征-即使B關(guān)閉或受困,A仍可繼續(xù)前進(jìn)。

這個(gè)原則可以而且應(yīng)該在基礎(chǔ)設(shè)施上下應(yīng)用。諸如SEDA(分階段事件驅(qū)動(dòng)架構(gòu))之類(lèi)的技術(shù)可用于在單個(gè)組件內(nèi)部進(jìn)行異步,同時(shí)保留易于理解的編程模型。在組件之間,原理是相同的-盡可能避免同步耦合。通常情況下,這兩個(gè)組件在任何情況下都沒(méi)有業(yè)務(wù)直接對(duì)話(huà)。在每個(gè)級(jí)別,將處理分解為階段或階段,并將它們異步連接,對(duì)于擴(kuò)展至關(guān)重要。

最佳實(shí)踐#5:將處理轉(zhuǎn)移到異步流程

現(xiàn)在您已異步解耦,請(qǐng)將盡可能多的處理移動(dòng)到異步端。在快速回復(fù)請(qǐng)求的系統(tǒng)中,這可以大大減少請(qǐng)求者所經(jīng)歷的延遲。在web站點(diǎn)或交易系統(tǒng)中,用數(shù)據(jù)或執(zhí)行延遲(我們完成所有工作的速度有多快)換取用戶(hù)延遲(用戶(hù)得到響應(yīng)的速度有多快)是值得的?;顒?dòng)跟蹤,計(jì)費(fèi),結(jié)算和報(bào)告是屬于后臺(tái)的處理的明顯示例。但是,處理主要用例的重要步驟通常可以分解為異步運(yùn)行。任何可以等待的東西都應(yīng)該等待。

同樣重要但同樣重要的是異步可以大大降低基礎(chǔ)設(shè)施成本。同步執(zhí)行操作會(huì)迫使您根據(jù)峰值負(fù)載擴(kuò)展基礎(chǔ)架構(gòu)-它需要在最后一秒處理最糟糕的第二天。但是,將昂貴的處理轉(zhuǎn)移到異步流可以讓您根據(jù)平均負(fù)載而不是峰值來(lái)擴(kuò)展基礎(chǔ)架構(gòu)。隊(duì)列不是需要立即處理所有請(qǐng)求,而是隨著時(shí)間的推移擴(kuò)展處理,從而抑制峰值。系統(tǒng)負(fù)載越尖銳或變化越大,這種優(yōu)勢(shì)就越大。

最佳實(shí)踐#6:在所有級(jí)別進(jìn)行虛擬化

虛擬化和抽象無(wú)處不在,遵循舊的計(jì)算機(jī)科學(xué)格言,即每個(gè)問(wèn)題的解決方案都是另一個(gè)層次的間接。操作系統(tǒng)抽象硬件。許多現(xiàn)代語(yǔ)言中的虛擬機(jī)抽象了操作系統(tǒng)。對(duì)象關(guān)系映射層抽象數(shù)據(jù)庫(kù)。負(fù)載平衡器和虛擬IP抽象網(wǎng)絡(luò)端點(diǎn)。當(dāng)我們通過(guò)功能和數(shù)據(jù)劃分來(lái)擴(kuò)展我們的基礎(chǔ)架構(gòu)時(shí),這些分區(qū)的額外虛擬化水平變得至關(guān)重要。

例如,在eBay,我們虛擬化數(shù)據(jù)庫(kù)。應(yīng)用程序與數(shù)據(jù)庫(kù)的邏輯表示交互,然后通過(guò)配置將其映射到特定的物理機(jī)器和實(shí)例。應(yīng)用程序類(lèi)似地從拆分路由邏輯中抽象出來(lái),拆分路由邏輯將特定記錄(例如,用戶(hù)XYZ的記錄)分配給特定分區(qū)。這兩種抽象都是在我們自己開(kāi)發(fā)的O/R層實(shí)現(xiàn)的。這允許操作團(tuán)隊(duì)在物理主機(jī)之間重新平衡邏輯主機(jī),通過(guò)分離它們,合并它們或移動(dòng)它們-所有這些都不需要觸及應(yīng)用程序代碼。

我們同樣虛擬化搜索引擎。為了檢索搜索結(jié)果,聚合器組件在多個(gè)分區(qū)上并行化查詢(xún),并使高度分區(qū)的搜索網(wǎng)格作為一個(gè)邏輯索引顯示給客戶(hù)端。

這里的動(dòng)機(jī)不僅是程序員的便利性,還有操作靈活性。硬件和軟件系統(tǒng)發(fā)生故障,需要重新路由請(qǐng)求。添加,移動(dòng)和刪除組件,計(jì)算機(jī)和分區(qū)。通過(guò)明智地使用虛擬化,您的基礎(chǔ)架構(gòu)的更高級(jí)別可以幸免于未發(fā)現(xiàn)這些變化,因此您可以自由地制作它們。虛擬化使得擴(kuò)展基礎(chǔ)架構(gòu)成為可能,因?yàn)樗沟脭U(kuò)展可管理。

最佳實(shí)踐#7:正確緩存

擴(kuò)展的最后一個(gè)組成部分是明智地使用緩存。這里的具體建議不太普遍,因?yàn)樗鼈兺叨纫蕾?lài)于用例的細(xì)節(jié)。在一天結(jié)束時(shí),高效緩存系統(tǒng)的目標(biāo)是在存儲(chǔ)限制內(nèi)最大化緩存命中率,滿(mǎn)足可用性要求以及對(duì)陳舊性的容忍度。事實(shí)證明,這種平衡可能非常難以實(shí)現(xiàn)。一旦受到打擊,我們的經(jīng)驗(yàn)表明,它也很可能隨著時(shí)間而改變。

例如,最明顯的緩存機(jī)會(huì)來(lái)自緩慢變化的讀取主要數(shù)據(jù)-元數(shù)據(jù),配置和靜態(tài)數(shù)據(jù)。在eBay,我們積極地緩存這類(lèi)數(shù)據(jù),并使用拉動(dòng)和推送方法的組合,以使系統(tǒng)在面對(duì)更新時(shí)合理地保持同步。減少對(duì)相同數(shù)據(jù)的重復(fù)請(qǐng)求可以而且確實(shí)產(chǎn)生重大影響。更具挑戰(zhàn)性的是快速變化的讀寫(xiě)數(shù)據(jù)。在大多數(shù)情況下,我們故意在eBay上回避這些挑戰(zhàn)。我們傳統(tǒng)上沒(méi)有在請(qǐng)求之間進(jìn)行任何臨時(shí)會(huì)話(huà)數(shù)據(jù)的緩存。我們同樣不會(huì)在應(yīng)用程序?qū)又芯彺婀蚕順I(yè)務(wù)對(duì)象,如項(xiàng)目或用戶(hù)數(shù)據(jù)。我們明確地根據(jù)可用性和正確性來(lái)緩存這些數(shù)據(jù)的潛在好處。應(yīng)該注意的是,其他網(wǎng)站確實(shí)采取不同的方法,做出不同的權(quán)衡,并且也是成功的。

毫不奇怪,很可能有太多好事。為緩存分配的內(nèi)存越多,可用于為單個(gè)請(qǐng)求提供服務(wù)的可用性就越少。在通常受內(nèi)存限制的應(yīng)用層中,這是一個(gè)非常真實(shí)的權(quán)衡。但更重要的是,一旦你開(kāi)始依賴(lài)緩存,并采取了極其誘人的步驟來(lái)縮小主要系統(tǒng)以處理緩存未命中,那么沒(méi)有它,你的基礎(chǔ)設(shè)施可能無(wú)法生存。一旦您的主系統(tǒng)無(wú)法再直接處理負(fù)載,您的站點(diǎn)的可用性現(xiàn)在取決于緩存的100%正常運(yùn)行時(shí)間-這是一種潛在的危險(xiǎn)情況。即使像重新平衡,移動(dòng)或冷啟動(dòng)緩存這樣的常規(guī)操作也會(huì)成為問(wèn)題。

如果操作正確,一個(gè)好的緩存系統(tǒng)可以將您的縮放曲線(xiàn)彎曲到線(xiàn)性以下-后續(xù)請(qǐng)求從緩存中便宜地檢索數(shù)據(jù),而不是相對(duì)更昂貴的主存儲(chǔ)。另一方面,緩存不佳會(huì)帶來(lái)大量額外的開(kāi)銷(xiāo)和可用性挑戰(zhàn)。我還沒(méi)有看到一個(gè)沒(méi)有重要緩存機(jī)會(huì)的系統(tǒng)。但關(guān)鍵是要確保您的緩存策略適合您的情況。

總結(jié)

可伸縮性有時(shí)被稱(chēng)為“非功能性需求”,暗示它與功能無(wú)關(guān),并強(qiáng)烈暗示它不那么重要。沒(méi)有東西會(huì)離事實(shí)很遠(yuǎn)。相反,我想說(shuō),可擴(kuò)展性是功能的先決條件-一個(gè)“優(yōu)先級(jí)為0”的要求,如果有的話(huà)。

我希望您發(fā)現(xiàn)這些最佳實(shí)踐的描述很有用,并且它們可以幫助您以新的方式思考您自己的系統(tǒng),無(wú)論其規(guī)模如何。

參考

eBay's Architectural Principles(video)

Werner Vogels on scalability

Dan Pritchett on You Scaled Your What?

The Coming of the Shard

Trading Consistency for Availability in Distributed Architectures

Eric Brewer on the CAP Theorem

SEDA:An Architecture for Well-Conditioned,Scalable Internet Services

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于超級(jí)架構(gòu)師,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪(fǎng)
投稿采訪(fǎng)
出海管家
出海管家