色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

可伸縮性的最差實(shí)踐

  相關(guān)文章:可伸縮性原則

  英文原文:Scalability Worst Practices

  引言

  在擴(kuò)展大量大型的分布式系統(tǒng)期間,我有機(jī)會(huì)觀察(并實(shí)踐)了一些最差實(shí)踐。這些最差實(shí)踐中的大部分在開(kāi)始時(shí)都沒(méi)有危害,但如果疏忽大意,它們就會(huì)對(duì)系統(tǒng)的發(fā)展和可伸縮性構(gòu)成危害。很多文章都聚焦于最佳實(shí)踐,以確保擁有一個(gè)易于維護(hù)和可伸縮的系統(tǒng),但在本文中,我主要強(qiáng)調(diào)的則是一些應(yīng)該規(guī)避的最差實(shí)踐。

  技術(shù)

  沒(méi)有任何一種技術(shù)或架構(gòu)能實(shí)現(xiàn)所有的需求。了解何時(shí)該反思現(xiàn)有的方法、如何拓寬視野以超越局部范圍、或如何進(jìn)行依賴的有效控制,這些都是可伸縮性的關(guān)鍵特性。讓我們進(jìn)一步分別研究一下。

  金錘子

  金錘子起源于一條古老的諺語(yǔ):如果你只有一把錘子,那么任何東西在你眼里都是一枚釘子。很多開(kāi)發(fā)人員都局限在僅使用一種技術(shù)的觀念中——其代價(jià)是不得不使用選定的技術(shù)來(lái)構(gòu)建和維護(hù)基礎(chǔ)設(shè)施,即便已經(jīng)存在另一種技術(shù)更適用于特定問(wèn)題域的功能和抽象。強(qiáng)行把一種技術(shù)用在它所不擅長(zhǎng)的方面,有時(shí)會(huì)適得其反。

  舉例來(lái)說(shuō),持久化鍵-值對(duì)問(wèn)題的常見(jiàn)解決方案是使用數(shù)據(jù)庫(kù)。之所以常常這樣選擇是因?yàn)榻M織或開(kāi)發(fā)者有堅(jiān)實(shí)的數(shù)據(jù)庫(kù)實(shí)踐,針對(duì)許多問(wèn)題自然而然就會(huì)沿用同樣的解決途徑。當(dāng)數(shù)據(jù)庫(kù)的特性(關(guān)系完整性、鎖、連接和方案)成為瓶頸或阻礙了其伸縮擴(kuò)展時(shí),問(wèn)題也就出現(xiàn)了。這是因?yàn)?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用基于數(shù)據(jù)庫(kù)的解決方案要發(fā)展,其成本通常要比使用其它可用技術(shù)更為昂貴。隨著鍵-值存儲(chǔ)訪問(wèn)率的增加,數(shù)據(jù)庫(kù)并發(fā)模式的性能就開(kāi)始降低,而數(shù)據(jù)庫(kù)具備的高級(jí)特性卻被閑置。許多傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的替代方案都是針對(duì)這些缺點(diǎn)的,比如CouchDB、SimpleDB或BigTable。

  另一個(gè)常見(jiàn)的“錘子”就是總利用線程來(lái)進(jìn)行并發(fā)編程。盡管線程確實(shí)是針對(duì)并發(fā)的,但它們也帶來(lái)了成本,這些成本包括代碼復(fù)雜性的增加、以及由于目前線程的的鎖定和訪問(wèn)模型造成的組件編排(composability )方面的固有不足。由于如今最流行的編程語(yǔ)言都使用線程處理并發(fā),因此數(shù)千行代碼都含有競(jìng)態(tài)條件、潛在的死鎖和不一致的數(shù)據(jù)訪問(wèn)管理。有些正在成長(zhǎng)的社區(qū)提出了另一些并發(fā)方案,這些方案不存在線程的可伸縮性問(wèn)題,也就是由Erlang或Stackless Python提倡的并發(fā)模型。即便不在實(shí)際生產(chǎn)中選擇那些語(yǔ)言,研究一下它們的概念(比如消息傳遞或異步I/O)仍然是一種不錯(cuò)的實(shí)踐。

  資源濫用

  小范圍的問(wèn)題開(kāi)發(fā)者們一般都能處理得得心應(yīng)手:使用分析工具、了解算法的空間和時(shí)間復(fù)雜度、或者了解哪種場(chǎng)合應(yīng)該用哪種列表實(shí)現(xiàn)。但并非每個(gè)人都善于認(rèn)識(shí)到大型系統(tǒng)的約束條件,比如識(shí)別共享資源的性能要求、了解服務(wù)的各種客戶、或發(fā)掘數(shù)據(jù)庫(kù)的訪問(wèn)模式。

  應(yīng)用程序?qū)崿F(xiàn)伸縮性的普遍方法是不斷橫向部署冗余的、無(wú)狀態(tài)的、彼此不共享內(nèi)容的服務(wù),以此作為最理想的體系架構(gòu)。但以我的經(jīng)驗(yàn)看來(lái),這種擴(kuò)展往往會(huì)忽視新增服務(wù)對(duì)共享資源的影響。

  比如說(shuō),如果一個(gè)特定的服務(wù)使用數(shù)據(jù)庫(kù)作為持久存儲(chǔ),它通常通過(guò)一個(gè)線程池來(lái)管理數(shù)據(jù)庫(kù)連接。使用池是不錯(cuò)的方法,有助于避免進(jìn)行過(guò)多的數(shù)據(jù)庫(kù)連接處理。然而數(shù)據(jù)庫(kù)仍然是共享資源,除了單個(gè)池配置,還必須對(duì)所有池從總體上進(jìn)行管理。下面兩個(gè)實(shí)踐就會(huì)導(dǎo)致失敗:

  1. 持續(xù)增加服務(wù)數(shù),但并不減小池的最大數(shù)。
  2. 增大單個(gè)池的大小,而不減小服務(wù)數(shù)量。

  以上兩種情況中,除了按性能要求配置應(yīng)用之外,連接的總數(shù)也必須加以管理。此外,還要持續(xù)監(jiān)控?cái)?shù)據(jù)庫(kù)的容量,以保持連接均衡。

  處理共享資源的可用性至關(guān)重要,準(zhǔn)確的說(shuō),這是因?yàn)樗鼈円坏┦В捎谄?ldquo;共享”的本質(zhì),失效會(huì)對(duì)系統(tǒng)造成全面的影響,而非孤立存在。

  大泥球

  依賴是很多系統(tǒng)討厭卻又必不可少的東西,不積極地處理好依賴及其版本會(huì)損害靈活性和可伸縮性。

  代碼的依賴管理有多種不同的模式:

  • 同時(shí)編譯整個(gè)代碼集
  • 基于已知版本選取構(gòu)件和服務(wù)
  • 發(fā)布的模型和服務(wù)所有變更都向后兼容

  讓我們看看這些情形。首先,在大泥球模式下,整個(gè)系統(tǒng)作為一個(gè)單元編譯和部署。這種模式擁有明顯的優(yōu)勢(shì),也就是將依賴管理交給編譯器處理,并能提前捕獲一些問(wèn)題,但它會(huì)因每次都部署整個(gè)系統(tǒng)(包括測(cè)試、交付和大范圍變化引起的風(fēng)險(xiǎn))而引發(fā)可伸縮性的問(wèn)題。在這種模式下,會(huì)更難隔離系統(tǒng)的變化。

  在第二種模式中,依賴都是按需挑選的,但是變化經(jīng)過(guò)依賴傳遞之后依舊出現(xiàn)第一種模式一樣的難題。

  第三種模式中,服務(wù)負(fù)責(zé)依賴的版本化,并向客戶端提供向后兼容的接口。這明顯減輕了客戶端的負(fù)擔(dān),從而允許逐步升級(jí)到新的模型和服務(wù)接口。此外,當(dāng)數(shù)據(jù)需要轉(zhuǎn)換的時(shí)候,它是依靠服務(wù)而不是客戶端完成的——這進(jìn)一步穩(wěn)固了隔離性。向后兼容的變更意味著打補(bǔ)丁、升級(jí)和回滾都不能干擾客戶端操作。

  采用變更能向后兼容的服務(wù)體系架構(gòu)在最大程度上避免了依賴問(wèn)題。它同時(shí)方便了在受控環(huán)境下進(jìn)行獨(dú)立測(cè)試,隔離了客戶端和版本化數(shù)據(jù)的變化。這三個(gè)優(yōu)點(diǎn)對(duì)隔離變化來(lái)說(shuō)都很重要。最近發(fā)布的Google Protocol Buffers項(xiàng)目也在倡導(dǎo)向后兼容的服務(wù)模型和接口。

  全部打包還是部分打包

  處理依賴時(shí)要考慮的另一件事情是如何對(duì)應(yīng)用內(nèi)容打包。

  在一些場(chǎng)景中,比如Amazon Machine Images或Google AppEngine應(yīng)用,它們的整個(gè)應(yīng)用和所有的依賴都一起打包發(fā)布。這種囊括一切的打包方法保持了應(yīng)用的自包含,但它增加了包的總大小,而且應(yīng)用中任何地方的一個(gè)小小改變,都會(huì)迫使系統(tǒng)重新部署整個(gè)應(yīng)用包(甚至對(duì)同一臺(tái)物理機(jī)器上許多應(yīng)用使用的共享庫(kù)也是如此)。

  替代方案是將應(yīng)用的依賴移出主機(jī)系統(tǒng),令應(yīng)用包只包含依賴圖的若干部分。這控制了包的大小,但由于應(yīng)用在能提供服務(wù)之前需要將特定的組件傳遞到每臺(tái)機(jī)器上,所以增加了部署配置。依賴項(xiàng)目沒(méi)有立即準(zhǔn)備好、機(jī)器沒(méi)有經(jīng)常測(cè)試、抑或是依賴錯(cuò)誤,由于以上種種,不將整個(gè)包部署為自包含的方式會(huì)制約將應(yīng)用部署到異構(gòu)的、非標(biāo)準(zhǔn)化的機(jī)器上。

  后一種方案——分成不同范圍(全局的、機(jī)器的、應(yīng)用的)去處理依賴——必然會(huì)增加疏漏和復(fù)雜性。它減少了配置和依賴隔離,增加了操作的復(fù)雜性。一般而言,隔離能增加可伸縮性,所以盡可能選用囊括一切的方法,除非有例外情況。

  無(wú)論在代碼還是在依賴處理中,最差實(shí)踐就是不清楚模塊間的關(guān)系,沒(méi)有規(guī)劃好模塊以便于對(duì)其進(jìn)行管理。未能增強(qiáng)控制是可伸縮性的一大絆腳石。

  忘記檢查時(shí)間

  在分布式系統(tǒng)中,通常的目標(biāo)是盡可能地將開(kāi)發(fā)者和負(fù)責(zé)分布式調(diào)用的復(fù)雜方法隔離開(kāi)來(lái)。這使主要的開(kāi)發(fā)工作集中于核心的業(yè)務(wù)邏輯上,而不用擔(dān)心失效恢復(fù)、超時(shí)以及其它分布式系統(tǒng)必需的需求。但是,讓遠(yuǎn)程調(diào)用看起來(lái)像本地調(diào)用一樣就意味著開(kāi)發(fā)者要像本地調(diào)用一樣編碼。

  我常發(fā)現(xiàn)很多代碼都期望所有的遠(yuǎn)程請(qǐng)求能及時(shí)完成,但這樣的期望是不合理的。比如說(shuō),Java在JDK1.5中僅為HTTPURLConnection類引入了讀超時(shí),而讓開(kāi)發(fā)者要么創(chuàng)建線程去殺死進(jìn)程,要么天真地等待響應(yīng)。

  Java中,另一個(gè)潛在的時(shí)間處理不合理的例子是DNS查找。在一個(gè)長(zhǎng)時(shí)間運(yùn)行的典型系統(tǒng)中,執(zhí)行完最初的DNS查找之后,如果不進(jìn)行明確的配置,結(jié)果會(huì)緩存在JVM的生命期內(nèi)。如果外部系統(tǒng)更改了主機(jī)的IP地址,將不能正確處理該條目,而且在很多情況下,因?yàn)榫幊虝r(shí)沒(méi)有設(shè)置連接超時(shí)時(shí)間,連接就會(huì)被掛起。

  為了對(duì)系統(tǒng)進(jìn)行合適的伸縮擴(kuò)展,為請(qǐng)求處理分配好時(shí)間是極其重要的。有很多方法可以實(shí)現(xiàn),有一些是語(yǔ)言內(nèi)置的(像Erlang),其它的則作為庫(kù)的形式提供,比如libevent或JavaNIO。拋開(kāi)實(shí)現(xiàn)語(yǔ)言或架構(gòu)不談,正確地管理操作等待時(shí)間是非常必要的。

  運(yùn)行時(shí)

  建立一個(gè)符合成本效益的可擴(kuò)展方案、處理好依賴、預(yù)先考慮到失效都是創(chuàng)建優(yōu)秀架構(gòu)的各方面要求。而在生產(chǎn)環(huán)境中,系統(tǒng)易于部署和運(yùn)維的能力也同等重要。這里同樣有很多不利于系統(tǒng)可伸縮性的最差實(shí)踐。

  英雄模式

  運(yùn)維問(wèn)題普遍的解決方案是有一個(gè)“英雄”(關(guān)鍵性人物),他能處理、并經(jīng)常處理大部分的操作需求。在小規(guī)模環(huán)境中,當(dāng)某個(gè)人有天賦和能力熟悉整個(gè)系統(tǒng)(包括保持系統(tǒng)正常運(yùn)行的許多細(xì)節(jié)之處),英雄模式可以正常運(yùn)行。盡管這是最常見(jiàn)的實(shí)施方案之一,但對(duì)擁有許多組件的大型系統(tǒng)而言,這種方法就不能進(jìn)行伸縮擴(kuò)展了。

  在沒(méi)有形式說(shuō)明的情況下,“英雄”往往要理解服務(wù)依賴,牢記如何開(kāi)、關(guān)特性,或了解其他人已經(jīng)遺忘了的系統(tǒng)。“英雄”雖然至關(guān)重要,但他不應(yīng)該是一個(gè)個(gè)體。

  我認(rèn)為英雄模式最好的解決方案是自動(dòng)化。如果組織的情況允許,讓個(gè)人在團(tuán)隊(duì)之間輪換也有幫助。在銀行里,休假有時(shí)是強(qiáng)制性的,好讓“你這里不行,要到我的機(jī)器上做”之類的問(wèn)題及時(shí)暴露出來(lái)。

  非自動(dòng)化

  系統(tǒng)過(guò)度依賴于人工干預(yù)往往是存在“英雄”的后果,這面臨著可重復(fù)生產(chǎn)能力的問(wèn)題和“英雄”出現(xiàn)意外情況帶來(lái)的問(wèn)題。能重現(xiàn)特定的構(gòu)建、部署和環(huán)境很重要,而明確定義的元數(shù)據(jù)控制下的自動(dòng)化是實(shí)現(xiàn)可重復(fù)能力的成功關(guān)鍵。

  在一些開(kāi)源項(xiàng)目中,工件的發(fā)布過(guò)程依賴于個(gè)體開(kāi)發(fā)者在自己工作站上構(gòu)建工件,沒(méi)有任何措施保證產(chǎn)生出來(lái)的工件版本能實(shí)際對(duì)應(yīng)到源碼控制系統(tǒng)中的某個(gè)分支。在這些情況下,完全有可能發(fā)布軟件,其代碼從未被提交到源碼控制系統(tǒng)。

  綜上所述,“英雄”的活動(dòng)應(yīng)該由自動(dòng)化取代,從而確保個(gè)人(或許多人)可以相對(duì)容易地替換其他人。自動(dòng)化的替代方案是增加流程——Clay Shirky為流程給出了一個(gè)有趣的定義:流程是對(duì)先前蠢行的內(nèi)在反應(yīng)。

  先前的蠢行在所難免——自動(dòng)化應(yīng)該吸取教訓(xùn)。

  監(jiān)控

  當(dāng)時(shí)間緊迫時(shí),監(jiān)控(比如測(cè)試)往往是第一個(gè)犧牲的環(huán)節(jié)。有時(shí),在我問(wèn)及有關(guān)組件的運(yùn)行時(shí)表現(xiàn)方面的細(xì)節(jié)問(wèn)題時(shí),總沒(méi)有答案。缺乏對(duì)運(yùn)行系統(tǒng)內(nèi)部的深入了解和迅速切入問(wèn)題的能力,不利于對(duì)從哪里入手和著手做什么做出正確攸關(guān)的決策。

  Orbitz很幸運(yùn)地?fù)碛芯媒?jīng)考驗(yàn)的監(jiān)控軟件,它們既能提供服務(wù)調(diào)用的細(xì)粒度詳細(xì)信息,也能精確顯現(xiàn)出問(wèn)題域的數(shù)據(jù)。來(lái)自監(jiān)控基礎(chǔ)設(shè)施的可用度量數(shù)據(jù)有利于快速有效地解決問(wèn)題。

  總結(jié)

  在不久前Amazon的S3出現(xiàn)服務(wù)中斷之后,Jeff Bezos說(shuō)道:遇到問(wèn)題的時(shí)候,我們知道直接原因,我們從那里入手分析并找到了根本原因,然后從根本上進(jìn)行了修復(fù),又向前邁進(jìn)了一步。

  軟件和系統(tǒng)的開(kāi)發(fā)是一個(gè)迭代的過(guò)程,在這個(gè)過(guò)程中,失敗和成功的機(jī)會(huì)并存。簡(jiǎn)單但較難伸縮的解決方案有其一席之地,特別是計(jì)劃或應(yīng)用尚處于不成熟的階段。“好”和“完美”不是對(duì)立的。但隨著系統(tǒng)的日臻完善,應(yīng)該除去其中的那些最差實(shí)踐,這樣,成功也就是理所當(dāng)然的了。

  非常感謝Monika Szymanski對(duì)本文初稿提出的建議。

  關(guān)于作者

  Brian Zimmer是旅游業(yè)新創(chuàng)企業(yè)Yapta的架構(gòu)師,是一位受人尊敬的開(kāi)源社區(qū)成員,也是Python軟件基金會(huì)的成員。他之前作為高級(jí)架構(gòu)師服務(wù)于Orbitz。他的博客在http://bzimmer.ziclix.com

  英文原文:Scalability Worst Practices。

it知識(shí)庫(kù)可伸縮性的最差實(shí)踐,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 襄汾县| 噶尔县| 静海县| 佳木斯市| 松滋市| 庆城县| 虹口区| 綦江县| 图片| 丘北县| 芜湖市| 景洪市| 昌图县| 且末县| 海盐县| 泗阳县| 贺州市| 尼木县| 漳州市| 太白县| 东丽区| 镇远县| 出国| 广东省| 正宁县| 襄城县| 安徽省| 瓦房店市| 巴彦县| 陕西省| 扎兰屯市| 宝坻区| 涟源市| 区。| 平和县| 汤阴县| 泾阳县| 古蔺县| 博客| 延吉市| 珠海市|