<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    一切皆可抽象

    大而無形 庖丁解牛 厚積薄發(fā) 滌慮玄覽
       ::  ::  ::  ::  :: 管理

    作者 Randy Shoup譯者 郭曉剛 發(fā)布于 2008年6月12日 下午7時(shí)5分

    社區(qū)
    Architecture
    主題
    設(shè)計(jì),
    性能和可伸縮性
    標(biāo)簽
    eBay

    在eBay,可伸縮性是我們每天奮力抵抗的一大架構(gòu)壓力。我們所做的每一項(xiàng)架構(gòu)及設(shè)計(jì)決策,身前身后都能看到它的蹤影。當(dāng)我們面對的是全世界數(shù)以億計(jì)的用戶,每天的頁面瀏覽量超過10億,系統(tǒng)中的數(shù)據(jù)量要用皮字節(jié)(1015或250)來計(jì)算——可伸縮性是生死交關(guān)的問題。

    相關(guān)廠商內(nèi)容

    SOY Framework:Java富客戶端快速開發(fā)框架

    視頻演講:開放平臺技術(shù)架構(gòu)剖析

    活動:體驗(yàn)基于OpenSolaris的Web/企業(yè)應(yīng)用(8.30 杭州)

    可伸縮性最佳實(shí)踐:來自eBay的經(jīng)驗(yàn)

    免費(fèi)迷你書下載:領(lǐng)域驅(qū)動設(shè)計(jì)精簡版

    相關(guān)贊助商

    [[InfoQ中文站架構(gòu)社區(qū)|http://www.infoq.com/cn/architecture/],關(guān)注設(shè)計(jì)、技術(shù)趨勢以及架構(gòu)師所感興趣的話題,通過新聞、文章、視頻訪談和演講以及迷你書等為中國架構(gòu)社區(qū)提供一流資訊。

    在一個(gè)可伸縮的架構(gòu)中,資源的消耗應(yīng)該隨負(fù)載線性(或更佳)上升,負(fù)載可由用戶流量、數(shù)據(jù)量等測量。如果說性能衡量的是每一工作單元所需的資源消 耗,可伸縮性則是衡量當(dāng)工作單元的數(shù)量或尺寸增加時(shí),資源消耗的變化情況。換句話說,可伸縮性是整個(gè)價(jià)格-性能曲線的形狀,而不是曲線上某一點(diǎn)的取值。

    可伸縮性有很多側(cè)面——事務(wù)的方面、運(yùn)營的方面、還有開發(fā)的方面。我們在改善一個(gè)Web系統(tǒng)的事務(wù)吞吐量的過程中學(xué)到了很多經(jīng)驗(yàn),本文總結(jié)了其中若 干關(guān)鍵的最佳實(shí)踐。可能很多最佳實(shí)踐你會覺得似曾相識,也可能有素未謀面的。這些都是開發(fā)和運(yùn)營eBay網(wǎng)站的眾人的集體經(jīng)驗(yàn)結(jié)晶。

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

    相關(guān)的功能部分應(yīng)該合在一起,不相關(guān)的功能部分應(yīng)該分割開來——不管你把它叫做SOA、功能分解還是工程秘訣。而且,不相關(guān)的功能之間耦合程度越松散,就越能靈活地獨(dú)立伸縮其中的一部分。

    在編碼層次,我們無時(shí)不刻都在運(yùn)用這條原則。JAR文件、包、Bundle等等,都是用來隔離和抽象功能的機(jī)制。

    在應(yīng)用層次,eBay將不同的功能劃分成幾個(gè)應(yīng)用程序池。銷售功能由一組應(yīng)用服務(wù)器運(yùn)行,投標(biāo)功能由另一組負(fù)責(zé),搜索又是另外一組服務(wù)器。我們把總 共約16,000臺應(yīng)用服務(wù)器分成220個(gè)池。這樣就可以根據(jù)某項(xiàng)功能的資源消耗,單獨(dú)地伸縮其中一個(gè)池。我們也因此得以進(jìn)一步隔離及合理化資源依賴關(guān)系 ——比如銷售池只需要訪問后臺資源的一個(gè)相對較小的子集。

    在數(shù)據(jù)庫層次,我們也采取同樣的做法。eBay沒有無所不包的單一數(shù)據(jù)庫,相反我們有一組數(shù)據(jù)庫主機(jī)存放用戶數(shù)據(jù)、一組存放商品數(shù)據(jù)、一組存放購買數(shù)據(jù)……總共1000個(gè)邏輯數(shù)據(jù)庫分布在400臺物理主機(jī)上。同樣,這種做法讓我們得以單獨(dú)為某一類數(shù)據(jù)伸縮其數(shù)據(jù)庫設(shè)施。

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

    按功能分割對我們的幫助很大,但單憑它還不足以得到完全可伸縮的架構(gòu)。即使將功能一一解耦,單項(xiàng)功能的資源需求隨著時(shí)間增長,仍然有可能超出單一系 統(tǒng)的能力。我們常常提醒自己,“沒有分割就沒有伸縮”。在單項(xiàng)功能內(nèi)部,我們需要能把工作負(fù)載分解成許多我們有能力駕馭的小單元,讓每個(gè)單元都能維持良好 的性能價(jià)格比。這就是水平分割出場的時(shí)候了。

    在應(yīng)用層次,由于eBay將各種交互都設(shè)計(jì)成無狀態(tài)的,所以水平分割是輕而易舉之事。用標(biāo)準(zhǔn)的負(fù)載均衡服務(wù)器來路由進(jìn)入的流量。所有應(yīng)用服務(wù)器都是 均等的,而且任何服務(wù)器都不會維持事務(wù)性的狀態(tài),因此負(fù)載均衡可以任意選擇應(yīng)用服務(wù)器。如果需要更多處理能力,只需要簡單地增加新的應(yīng)用服務(wù)器。

    數(shù)據(jù)庫層次的問題比較有挑戰(zhàn)性,原因是數(shù)據(jù)天生就是有狀態(tài)的。我們會按照主要的訪問路徑對數(shù)據(jù)作水平分割(或稱為“sharding”)。例如用戶 數(shù)據(jù)目前被分割到20臺主機(jī)上,每臺主機(jī)存放1/20的用戶。隨著用戶數(shù)量的增長,以及每個(gè)用戶的數(shù)據(jù)量增長,我們會增加更多的主機(jī),將用戶分散到更多的 機(jī)器上去。商品數(shù)據(jù)、購買數(shù)據(jù)、帳戶數(shù)據(jù)等等也都用同樣的方式處理。用例不同,我們分割數(shù)據(jù)的方案也不同:有些是對主鍵簡單取模(ID尾數(shù)為1的放到第一 臺主機(jī),尾數(shù)為二的放到下一臺,以此類推),有些是按照ID的區(qū)間分割(1-1M、1-2M等等),有些用一個(gè)查找表,還有些是綜合以上的策略。不過具體 的分割方案如何,總的思想是支持?jǐn)?shù)據(jù)分割及重分割的基礎(chǔ)設(shè)施在可伸縮性上遠(yuǎn)比不支持的優(yōu)越。

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

    看到這里,你可能在疑惑按功能劃分?jǐn)?shù)據(jù)和水平劃分?jǐn)?shù)據(jù)的實(shí)踐如何滿足事務(wù)要求。畢竟,幾乎任何有意義的操作都要更新一個(gè)以上的實(shí)體——立即就可以舉 出用戶和商品的例子。正統(tǒng)的廣為人知的答案是:建立跨資源的分布式事務(wù),用兩段式提交來保證要么所有資源全都更新,要么全都不更新。很不幸,這種悲觀方案 的成本很可觀。伸縮、性能和響應(yīng)延遲都受到協(xié)調(diào)成本的反面影響,隨著依賴的資源數(shù)量和客戶數(shù)量的上升,這些指標(biāo)都會以幾何級數(shù)惡化。可用性亦受到限制,因 為所有依賴的資源都必須就位。實(shí)用主義的答案是,對于不相關(guān)的系統(tǒng),放寬對它們的跨系統(tǒng)事務(wù)的保證。

    左右逢源是辦不到的。保證跨多個(gè)系統(tǒng)或分區(qū)之間的即時(shí)的一致性,通常既無必要,也不現(xiàn)實(shí)。Inktomi的Eric Brewer十年前提出的CAP公理是這樣說的:分布式系統(tǒng)的三項(xiàng)重要指標(biāo)——一致性(Consistency)、可用性(Availability)和 分區(qū)耐受性(Partition-tolerance)——在任意時(shí)刻,只有兩項(xiàng)能同時(shí)成立。對于高流量的網(wǎng)站來說,我們必須選擇分區(qū)耐受性,因?yàn)樗菍?shí) 現(xiàn)可伸縮的根本。對于24x7運(yùn)行的網(wǎng)站,選擇可用性也是理所當(dāng)然的。于是只好放棄即時(shí)一致性(immediate consistency)。

    在eBay,我們絕對不允許任何形式的客戶端或者分布式事務(wù)——因此絕不需要兩段式提交。在某些經(jīng)過仔細(xì)定義的情形下,我們會將作用于同一個(gè)數(shù)據(jù)庫 的若干語句捆綁成單個(gè)事務(wù)性的操作。而對于絕大部分操作,單條語句是自動提交的。雖然我們故意放寬正統(tǒng)的ACID屬性,以致不能在所有地方保證即時(shí)一致 性,但現(xiàn)實(shí)的結(jié)果是大部分系統(tǒng)在絕大部分時(shí)間都是可用的。當(dāng)然我們也采用了一些技術(shù)來幫助系統(tǒng)達(dá)到最終的一致性(eventual consistency):周密調(diào)整數(shù)據(jù)庫操作的次序、異步恢復(fù)事件,以及數(shù)據(jù)核對(reconciliation)或者集中決算(settlement batches)。具體選擇哪種技術(shù)要根據(jù)特定用例對一致性的需求來決定。

    對于架構(gòu)師和系統(tǒng)的設(shè)計(jì)者來說,關(guān)鍵是要明白一致性并非“有”和“沒有”的單選題。現(xiàn)實(shí)中大多數(shù)的用例都不要求即時(shí)一致性。正如我們經(jīng)常根據(jù)成本和其他壓力因素來權(quán)衡可用性的高低,一致性也同樣可以量體裁衣,根據(jù)特定操作的需要而保證適當(dāng)程度的一致性。 

    最佳實(shí)踐 #4:用異步策略解耦程序

    提高可伸縮性的另一項(xiàng)關(guān)鍵措施是積極地采取異步策略。如果組件A同步調(diào)用組件B,那么A和B就是緊密耦合的,而緊耦合的系統(tǒng)其可伸縮性特征是各部分 必須共同進(jìn)退——要伸縮A必須同時(shí)伸縮B。同步調(diào)用的組件在可用性方面也面臨著同樣的問題。我們回到最基本的邏輯:如果A推出B,那么非B推出非A。也就 是說,若B不可用,則A也不可用。如果反過來A和B的聯(lián)系是異步的,不管是通過隊(duì)列、多播消息、批處理還是什么其他手段,它們就可以分別地伸縮。而且,此 時(shí)A和B的可用性特征是相互獨(dú)立的——即使B受困或者死掉,A仍然能夠繼續(xù)前進(jìn)。

    整個(gè)基礎(chǔ)設(shè)施從上到下都應(yīng)該貫徹這項(xiàng)原則。即使在單個(gè)組件內(nèi)部也可通過SEDA(分階段的事件驅(qū)動架構(gòu),Staged Event-Driven Architecture)等技術(shù)實(shí)現(xiàn)異步性,同時(shí)保持一個(gè)易于理解的編程模型。組件之間也遵守同樣的原則——盡可能避免同步帶來的耦合。在多數(shù)情況下, 兩個(gè)組件在任何事件中都不會有直接的業(yè)務(wù)聯(lián)系。在所有的層次,把過程分解為階段(stages or phases),然后將它們異步地連接起來,這是伸縮的關(guān)鍵。

    最佳實(shí)踐 #5:將過程轉(zhuǎn)變?yōu)楫惒降牧?/h3>

    用異步的原則解耦程序,盡可能將過程變?yōu)楫惒降摹τ谝罂焖夙憫?yīng)的系統(tǒng),這樣做可以從根本上減少請求者所經(jīng)歷的響應(yīng)延遲。對于網(wǎng)站或者交易系統(tǒng), 犧牲數(shù)據(jù)或執(zhí)行的延遲時(shí)間(完成全部工作的實(shí)踐)來換取用戶的延遲時(shí)間(用戶得到響應(yīng)的時(shí)間)是值得的。活動跟蹤、單據(jù)開付、決算和報(bào)表等處理過程顯然都 應(yīng)該屬于后臺活動。主要用例過程中常常有很多步驟可以進(jìn)一部分解成異步運(yùn)行。任何可以晚點(diǎn)再做的事情都應(yīng)該晚點(diǎn)再做。

    還有一個(gè)同等重要的方面認(rèn)識到的人不多:異步性可以從根本上降低基礎(chǔ)設(shè)施的成本。同步地執(zhí)行操作迫使你必須按照負(fù)載的峰值來配備基礎(chǔ)設(shè)施——即使在 任務(wù)最重的那一天里任務(wù)最重的那一秒,設(shè)施也必須有能力立即完成處理。而將昂貴的處理過程轉(zhuǎn)變?yōu)楫惒降牧鳎A(chǔ)設(shè)施就不需要按照峰值來配備,只需要滿足平 均負(fù)載。而且也不需要立即處理所有的請求,異步隊(duì)列可以將處理任務(wù)分?jǐn)偟捷^長的時(shí)間里,因而起到削峰的作用。系統(tǒng)的負(fù)載變化越大,曲線越多尖峰,就越能從 異步處理中得益。

    最佳實(shí)踐 #6:虛擬化所有層次

    虛擬化和抽象化無所不在,計(jì)算機(jī)科學(xué)里有一句老話:所有問題都可以通過增加一個(gè)間接層次來解決。操作系統(tǒng)是對硬件的抽象,而許多現(xiàn)代語言所用的虛擬 機(jī)又是對操作系統(tǒng)的抽象。對象-關(guān)系映射層抽象了數(shù)據(jù)庫。負(fù)載均衡器和虛擬IP抽象了網(wǎng)絡(luò)終端。當(dāng)我們通過分割數(shù)據(jù)和程序來提高基礎(chǔ)設(shè)施的可伸縮性,為各 種分割增加額外的虛擬層次就成為重中之重。

    在eBay,我們虛擬化了數(shù)據(jù)庫。應(yīng)用與邏輯數(shù)據(jù)庫交互,邏輯數(shù)據(jù)庫再按照配置映射到某個(gè)特定的物理機(jī)器和數(shù)據(jù)庫實(shí)例。應(yīng)用也抽象于執(zhí)行數(shù)據(jù)分割的 路由邏輯,路由邏輯會把特定的記錄(如用戶XYZ)分配到指定的分區(qū)。這兩類抽象都是在我們自己開發(fā)的O/R層上實(shí)現(xiàn)的。這樣虛擬化之后,我們的運(yùn)營團(tuán)隊(duì) 可以按需要在物理主機(jī)群上重新分配邏輯主機(jī)——分離、合并、移動——而完全不需要接觸應(yīng)用程序代碼。

    搜索引擎同樣是虛擬化的。為了得到搜索結(jié)果,一個(gè)聚合器組件會在多個(gè)分區(qū)上執(zhí)行并行的查詢,但這個(gè)高度分割的搜索網(wǎng)格在客戶看來只是單一的邏輯索引。

    以上種種措施并不只是為了程序員的方便,運(yùn)營上的靈活性也是一大動機(jī)。硬件和軟件系統(tǒng)都會故障,請求需要重新路由。組件、機(jī)器、分區(qū)都會不時(shí)增減、 移動。明智地運(yùn)用虛擬化,可使高層的設(shè)施對以上變化難得糊涂,你也就有了騰挪的余地。虛擬化使基礎(chǔ)設(shè)施的伸縮成為可能,因?yàn)樗股炜s變成可管理的。

    最佳實(shí)踐 #7:適當(dāng)?shù)厥褂镁彺?/h3>

    最后要適當(dāng)?shù)厥褂镁彺妗_@里給出的建議不一定普遍適用,因?yàn)榫彺媸欠窀咝O大地依賴于用例的細(xì)節(jié)。說到底,要在存儲約束、對可用性的需求、對陳舊數(shù) 據(jù)的容忍程度等條件下最大化緩存的命中率,這才是一個(gè)高效的緩存系統(tǒng)的最終目標(biāo)。經(jīng)驗(yàn)證明,要平衡眾多因素是極其困難的,即使暫時(shí)達(dá)到目標(biāo),情況也極可能 隨著時(shí)間而改變。

    最適合緩存的是很少改變、以讀為主的數(shù)據(jù)——比如元數(shù)據(jù)、配置信息和靜態(tài)數(shù)據(jù)。在eBay,我們積極地緩存這種類型的數(shù)據(jù),并且結(jié)合使用“推”和“ 拉”兩種方法保持系統(tǒng)在一定程度上的更新同步。減少對相同數(shù)據(jù)的重復(fù)請求能達(dá)到非常顯著的效果。頻繁變更、讀寫兼有的數(shù)據(jù)很難有效地緩存。在eBay,我 們大多有意識地回避這樣的難題。我們一直不對請求間短暫存在的會話數(shù)據(jù)作任何緩存。也不在應(yīng)用層緩存共享的業(yè)務(wù)對象,比如商品和用戶數(shù)據(jù)。我們有意地犧牲 緩存這些數(shù)據(jù)的潛在利益,換取可用性和正確性。在此必須指出,其他網(wǎng)站采取了不同的途徑,作了不同的取舍,也同樣取得了成功。

    好東西也會過猶不及。為緩存分配的內(nèi)存越多,能用來服務(wù)單個(gè)請求的內(nèi)存就越少。應(yīng)用層常常有內(nèi)存不足的壓力,因此這是非常現(xiàn)實(shí)的權(quán)衡。更重要的一 點(diǎn),當(dāng)你開始依賴于緩存,那么主要系統(tǒng)就只需要滿足緩存未命中時(shí)的處理要求,自然而然你就會想到可以削減主要系統(tǒng)。但當(dāng)你這樣做之后,系統(tǒng)就完全離不開緩 存了。現(xiàn)在主要系統(tǒng)沒辦法直接應(yīng)付全部流量,也就是說網(wǎng)站的可用性取決于緩存能否100%正常運(yùn)行——潛在的危局。哪怕是例行的操作,比如重新配置緩存資 源、把緩存移動到別的機(jī)器、冷啟動緩存服務(wù)器,都有可能引發(fā)嚴(yán)重的問題。

    做得好,緩存系統(tǒng)能讓可伸縮性的曲線向下彎曲,也就是比線性增長還要好——后續(xù)請求從緩存中取數(shù)據(jù)比從主存儲取數(shù)據(jù)成本低廉。反過來,緩存做得不好 會引入相當(dāng)多額外的經(jīng)常耗費(fèi),也會妨礙到可用性。我還沒見過哪個(gè)系統(tǒng)沒機(jī)會讓緩存大展拳腳的,關(guān)鍵是要根據(jù)具體情況找到適當(dāng)緩存策略。

    總結(jié)

    可伸縮性有時(shí)候被叫做“非功能性需求”,言下之意是它與功能無關(guān),也就比較不重要。這么說簡直錯(cuò)到了極點(diǎn)。我的觀點(diǎn)是,可伸縮性是功能的先決條件——優(yōu)先級為0的需求,比一切需求的優(yōu)先級都高。

    希望以上最佳實(shí)踐能對你有用,希望能幫助你從新的角度審視你的系統(tǒng),無論其規(guī)模如何。

    主站蜘蛛池模板: 亚洲天堂一区二区三区| 亚洲色自偷自拍另类小说| 亚洲国产综合第一精品小说| 人人玩人人添人人澡免费| 亚洲中文无码永久免| 久视频精品免费观看99| 亚洲蜜芽在线精品一区| 19禁啪啪无遮挡免费网站| 亚洲美女视频免费| 57PAO成人国产永久免费视频 | 亚洲免费在线观看| 国产av无码专区亚洲国产精品| 一级做a爰片久久毛片免费陪| 亚洲精品无码久久毛片| 国产三级在线免费观看| 亚洲国产无套无码av电影| 久久久久国产免费| 亚洲精品第五页中文字幕| 一区二区视频免费观看| 影音先锋在线免费观看| 久久丫精品国产亚洲av不卡| 182tv免费观看在线视频| 亚洲AV无码成人专区| 麻豆国产人免费人成免费视频| 国产亚洲视频在线观看| 亚洲精品你懂的在线观看| 久久国产高潮流白浆免费观看| 亚洲一区中文字幕在线电影网| 日韩免费电影在线观看| 成人片黄网站色大片免费观看cn| 亚洲国产精品国自产拍电影| 日本精品人妻无码免费大全| 香港特级三A毛片免费观看| 午夜免费福利网站| 国产精品免费看久久久香蕉| 亚洲成人午夜在线| 免费无码又爽又刺激高潮的视频 | 青青草原精品国产亚洲av| 岛国大片免费在线观看| 一级做a免费视频观看网站| 精品亚洲aⅴ在线观看|