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

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

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

    走在架構師的大道上 Jack.Wang's home

    Java, C++, linux c, C#.net 技術,軟件架構,領域建模,IT 項目管理 Dict.CN 在線詞典, 英語學習, 在線翻譯

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      195 Posts :: 3 Stories :: 728 Comments :: 0 Trackbacks

    作者 Randy Shoup譯者 郭曉剛 發(fā)布于 2008年6月12日 下午7時5分 社區(qū) Architecture 主題 設計, 性能和可伸縮性 標簽 eBay  原文地址:http://www.infoq.com/cn/articles/ebay-scalability-best-practices;jsessionid=13866DB9B34F7D438D3F56C4044EFB32

    在eBay,可伸縮性是我們每天奮力抵抗的一大架構壓力。我們所做的每一項架構及設計決策,身前身后都能看到它的蹤影。當我們面對的是全世界數(shù)以億計的用戶,每天的頁面瀏覽量超過10億,系統(tǒng)中的數(shù)據(jù)量要用皮字節(jié)(1015或250)來計算——可伸縮性是生死交關的問題。
           在一個可伸縮的架構中,資源的消耗應該隨負載線性(或更佳)上升,負載可由用戶流量、數(shù)據(jù)量等測量。如果說性能衡量的是每一工作單元所需的資源消 耗,可伸縮性則是衡量當工作單元的數(shù)量或尺寸增加時,資源消耗的變化情況。換句話說,可伸縮性是整個價格-性能曲線的形狀,而不是曲線上某一點的取值。

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

    最佳實踐 #1:按功能分割

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

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

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

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

    最佳實踐 #2:水平切分

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

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

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

    最佳實踐 #3:避免分布式事務

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

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

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

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

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

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

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

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

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

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

    最佳實踐 #6:虛擬化所有層次

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

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

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

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

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

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

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

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

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

    總結

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

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

    參考

    關于作者

    Randy Shoup是eBay的杰出架構師。從2004年起擔任eBay搜索基礎設施的主要架構師。在加入eBay之前,他是Tumbleweed Communications公司的總架構師,也曾在Oracle和Informatica擔任多個軟件開發(fā)和架構的職位。

    他經(jīng)常在業(yè)界的會議上講授可伸縮性和架構模式。

    閱讀英文原文:Scalability Best Practices: Lessons from eBay





    本博客為學習交流用,凡未注明引用的均為本人作品,轉載請注明出處,如有版權問題請及時通知。由于博客時間倉促,錯誤之處敬請諒解,有任何意見可給我留言,愿共同學習進步。
    posted on 2008-10-12 12:42 Jack.Wang 閱讀(2443) 評論(0)  編輯  收藏 所屬分類: 架構師篇
    主站蜘蛛池模板: 久久精品国产亚洲AV大全| 日本一道本不卡免费 | 粉色视频免费入口| 亚洲视频在线观看免费视频| 久久精品国产亚洲精品| 日本特黄特色aa大片免费| 麻豆视频免费播放| 一区二区三区福利视频免费观看| 一进一出60分钟免费视频| 亚洲AV无码专区在线电影成人| 亚洲国产精品线观看不卡| 亚洲av中文无码乱人伦在线播放| 亚洲无线一二三四区手机| 国产精品国产自线拍免费软件| 日本一区二区三区免费高清| 麻豆成人久久精品二区三区免费| 成人无码视频97免费| 一级特黄a大片免费| 色爽黄1000部免费软件下载| 精品亚洲成A人在线观看青青| 亚洲中文字幕无码爆乳| 亚洲一卡2卡3卡4卡乱码 在线| 亚洲综合色一区二区三区小说| 亚洲国产二区三区久久| 亚洲国产精品成人精品无码区| 亚洲精品亚洲人成在线观看| 国产亚洲成归v人片在线观看| 亚洲天堂在线视频| 亚洲欧洲精品成人久久奇米网| 波多野结衣中文一区二区免费| 免费一级毛片在线播放不收费| 国产在线98福利播放视频免费| 国产精品冒白浆免费视频| 国产一级淫片视频免费看| 免费人成网站7777视频| 亚洲国产午夜福利在线播放| 亚洲一级Av无码毛片久久精品| 亚洲日本乱码在线观看| 亚洲va久久久噜噜噜久久男同| 亚洲一区二区在线免费观看| 2022年亚洲午夜一区二区福利|