天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

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

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

  英文原文:Scalability Worst Practices

  引言

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

  技術(shù)

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

  金錘子

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

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

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

  資源濫用

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

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

  比如說,如果一個(gè)特定的服務(wù)使用數(shù)據(jù)庫作為持久存儲(chǔ),它通常通過一個(gè)線程池來管理數(shù)據(jù)庫連接。使用池是不錯(cuò)的方法,有助于避免進(jìn)行過多的數(shù)據(jù)庫連接處理。然而數(shù)據(jù)庫仍然是共享資源,除了單個(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ù)庫的容量,以保持連接均衡。

  處理共享資源的可用性至關(guān)重要,準(zhǔn)確的說,這是因?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ì),也就是將依賴管理交給編譯器處理,并能提前捕獲一些問題,但它會(huì)因每次都部署整個(gè)系統(tǒng)(包括測(cè)試、交付和大范圍變化引起的風(fēng)險(xiǎn))而引發(fā)可伸縮性的問題。在這種模式下,會(huì)更難隔離系統(tǒng)的變化。

  在第二種模式中,依賴都是按需挑選的,但是變化經(jīng)過依賴傳遞之后依舊出現(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)在最大程度上避免了依賴問題。它同時(shí)方便了在受控環(huán)境下進(jìn)行獨(dú)立測(cè)試,隔離了客戶端和版本化數(shù)據(jù)的變化。這三個(gè)優(yōu)點(diǎn)對(duì)隔離變化來說都很重要。最近發(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)用使用的共享庫也是如此)。

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

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

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

  忘記檢查時(shí)間

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

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

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

  為了對(duì)系統(tǒng)進(jìn)行合適的伸縮擴(kuò)展,為請(qǐng)求處理分配好時(shí)間是極其重要的。有很多方法可以實(shí)現(xiàn),有一些是語言內(nèi)置的(像Erlang),其它的則作為庫的形式提供,比如libevent或JavaNIO。拋開實(shí)現(xiàn)語言或架構(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)維問題普遍的解決方案是有一個(gè)“英雄”(關(guān)鍵性人物),他能處理、并經(jīng)常處理大部分的操作需求。在小規(guī)模環(huán)境中,當(dāng)某個(gè)人有天賦和能力熟悉整個(gè)系統(tǒng)(包括保持系統(tǒng)正常運(yùn)行的許多細(xì)節(jié)之處),英雄模式可以正常運(yùn)行。盡管這是最常見的實(shí)施方案之一,但對(duì)擁有許多組件的大型系統(tǒng)而言,這種方法就不能進(jìn)行伸縮擴(kuò)展了。

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

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

  非自動(dòng)化

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

  在一些開源項(xiàng)目中,工件的發(fā)布過程依賴于個(gè)體開發(fā)者在自己工作站上構(gòu)建工件,沒有任何措施保證產(chǎn)生出來的工件版本能實(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í),在我問及有關(guān)組件的運(yùn)行時(shí)表現(xiàn)方面的細(xì)節(jié)問題時(shí),總沒有答案。缺乏對(duì)運(yùn)行系統(tǒng)內(nèi)部的深入了解和迅速切入問題的能力,不利于對(duì)從哪里入手和著手做什么做出正確攸關(guān)的決策。

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

  總結(jié)

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

  軟件和系統(tǒng)的開發(fā)是一個(gè)迭代的過程,在這個(gè)過程中,失敗和成功的機(jī)會(huì)并存。簡單但較難伸縮的解決方案有其一席之地,特別是計(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)師,是一位受人尊敬的開源社區(qū)成員,也是Python軟件基金會(huì)的成員。他之前作為高級(jí)架構(gòu)師服務(wù)于Orbitz。他的博客在http://bzimmer.ziclix.com

  英文原文:Scalability Worst Practices。

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

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

主站蜘蛛池模板: 久久se视频精品视频在线 | 国产精品成人啪精品视频免费观看 | 美女用手扒开粉嫩的屁股 | 一边捏奶头一边啪高潮会怎么样 | 红豆视频免费资源观看 | 欧美午夜特黄AAAAAA片 | 性夜影院爽黄A爽免费动漫 性夜夜春夜夜爽AA片A | 欧美做真爱欧免费看 | 久久伊人久久 | 久久一本岛在免费线观看2020 | 久久夜色噜噜噜亚洲AV0000 | 亚洲精品第一综合99久久 | 欧美成人免费一区二区三区不卡 | 成人伊人青草久久综合网 | 亚洲AV无码国产精品午夜久久 | 国产在线亚洲精品观看不卡 | 中文在线观看免费网站 | 99久久伊人一区二区yy5o99 | 成人AV精品视频 | 国产精品免费视频播放 | 亚洲AV无码一区二区三区乱子伦 | 国产精品一区二区AV白丝在线 | 中俄两军在日本海等上空战略巡航 | 亚洲高清无在码在线无弹窗 | 亚洲色图影院 | 久久免费看少妇高潮A片特爽 | 欧美另类与牲交ZOZOZO | 久久国产亚洲精品AV麻豆 | 桃花在线观看播放 | 真实的强视频免费网站 | 精油按摩日本 | jizz国产丝袜18老师美女 | 日韩吃奶摸下AA片免费观看 | 成人亚洲视频在线观看 | 国产强奷糟蹋漂亮邻居在线观看 | 草莓国产视频免费观看 | 国产亚洲精品精品国产亚洲综合 | 暖暖 免费 日本 高清 在线1 | 在线看片韩国免费人成视频 | 亚洲视频在线观 | 国产精品美女久久久久AV超清 |