CONAN ZONE

          你越掙扎我就越興奮

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
          原文地址:http://www.theserverside.com/tt/articles/article.tss?l=ScalingYourJavaEEApplicationsPart2

          當(dāng)并發(fā)用戶數(shù)明顯的開始增長(zhǎng),你可能會(huì)不滿意一臺(tái)機(jī)器所能提供的性能,或者由于單個(gè)JVM實(shí)例gc的限制,你沒法擴(kuò)展你的java應(yīng)用,在這樣的情況下你可以做的另外的選擇是在多個(gè)JVM實(shí)例或多臺(tái)服務(wù)器上運(yùn)行你的系統(tǒng),我們把這種方法稱為水平擴(kuò)展。

          請(qǐng)注意,我們相信能夠在一臺(tái)機(jī)器的多個(gè)JVM上運(yùn)行系統(tǒng)的擴(kuò)展方式是水平擴(kuò)展方式,而非垂直擴(kuò)展方式。JVM實(shí)例之間的IPC機(jī)制是有限的,兩個(gè)JVM實(shí)例之間無法通過管道、共享內(nèi)存、信號(hào)量或指令來進(jìn)行通訊,不同的JVM進(jìn)程之間最有效的通訊方式是socket。簡(jiǎn)而言之,如果Java EE應(yīng)用如果擴(kuò)展到多個(gè)JVM實(shí)例中運(yùn)行,那么大多數(shù)情況下它也可以擴(kuò)展到多臺(tái)服務(wù)器上運(yùn)行。

          隨著計(jì)算機(jī)越來越便宜,性能越來越高,通過將低成本的機(jī)器群組裝為集群可以獲得超過那些昂貴的超級(jí)計(jì)算機(jī)所具備的計(jì)算能力。不過,大量的計(jì)算機(jī)也意味著增加了管理的復(fù)雜性以及更為復(fù)雜的編程模型,就像服務(wù)器節(jié)點(diǎn)之間的吞吐量和延時(shí)等問題。

          Java EE集群是一種成熟的技術(shù),我在TSS上寫了一篇名為“Uncover the Hood of J2EE Clustering”的文章來描述它的內(nèi)部機(jī)制。

          從失敗的項(xiàng)目中吸取的教訓(xùn)

          采用無共享的集群架構(gòu)


          Figure 3: share nothing cluster

          最具備擴(kuò)展性的架構(gòu)當(dāng)屬無共享的集群架構(gòu)。在這樣的集群中,每個(gè)節(jié)點(diǎn)具備完全相同的功能,并且不需要知道其他節(jié)點(diǎn)存在與否。負(fù)載均衡器(Load Balancer)來完成如何將請(qǐng)求分發(fā)給這些后臺(tái)的服務(wù)器實(shí)例。由于負(fù)載均衡器只是做一些簡(jiǎn)單的工作,例如分派請(qǐng)求、健康檢查和保持session,因此負(fù)載均衡器很少會(huì)成為瓶頸。如果后端的數(shù)據(jù)庫(kù)系統(tǒng)或其他的信息系統(tǒng)足夠的強(qiáng)大,那么通過增加更多的節(jié)點(diǎn),集群的計(jì)算能力可以得到線性的增長(zhǎng)。

          幾乎所有的Java EE提供商在他們的集群產(chǎn)品中都實(shí)現(xiàn)了HttpSession的failover功能,這樣即使在某些服務(wù)器節(jié)點(diǎn)不可用的情況下也仍然能夠保證客戶端的請(qǐng)求中的session信息不丟失,但這點(diǎn)其實(shí)是打破了無共享原則的。為了實(shí)現(xiàn)failover,同樣的session數(shù)據(jù)將會(huì)被兩個(gè)或多個(gè)節(jié)點(diǎn)共享,在我之前的文章中,我曾經(jīng)推薦除非是萬不得已,不要使用session failover。就像我文章中提到的,當(dāng)失敗發(fā)生時(shí),session failover功能并不能完全避免錯(cuò)誤,而且同時(shí)還會(huì)對(duì)性能和可擴(kuò)展性帶來?yè)p失。

          使用可擴(kuò)展的session復(fù)制機(jī)制

          為了讓用戶獲得更友好的體驗(yàn),有些時(shí)候可能必須使用session failover功能,這里最重要的在于選擇可擴(kuò)展的復(fù)制型產(chǎn)品或機(jī)制。不同的廠商會(huì)提供不同的復(fù)制方案 - 有些采用數(shù)據(jù)庫(kù)持久,有些采用中央集中的狀態(tài)服務(wù)器,而有些則采用節(jié)點(diǎn)間內(nèi)存復(fù)制的方式。最具可擴(kuò)展性的是成對(duì)節(jié)點(diǎn)的復(fù)制(paired node replication),這也是現(xiàn)在大部分廠商采用的方案,包括BEA Weblogic、JBoss和IBM Websphere,Sun在Glassfish V2以及以上版本也實(shí)現(xiàn)了成對(duì)節(jié)點(diǎn)的復(fù)制。最不可取的方案是數(shù)據(jù)庫(kù)持久session的方式。在我們實(shí)驗(yàn)室中曾經(jīng)測(cè)試過一個(gè)采用數(shù)據(jù)庫(kù)持久來實(shí)現(xiàn) session復(fù)制的項(xiàng)目,測(cè)試結(jié)果表明如果session對(duì)象頻繁更新的話,節(jié)點(diǎn)在三到四個(gè)時(shí)就會(huì)導(dǎo)致數(shù)據(jù)庫(kù)崩潰。

          采用collocated部署方式來取代分布式

          Java EE技術(shù),尤其是EJB,天生就是用來做分布式計(jì)算的。解耦業(yè)務(wù)功能和重用遠(yuǎn)程的組件使得多層的應(yīng)用模型得以流行。但對(duì)于可擴(kuò)展性而言,減少分布式的層次可能是一個(gè)好的選擇。

          在我們實(shí)驗(yàn)室曾經(jīng)以一個(gè)政府的項(xiàng)目測(cè)試過這兩種方式在同樣的服務(wù)器數(shù)量上的部署 - 一種是分布式的,一種是collocated方式的,如下圖所示:


          Figure 4: distributed structure

          Figure 5: collocated structure

          結(jié)果表明collocated式的部署方式比分布式的方式更具備可擴(kuò)展性。假設(shè)你應(yīng)用中的一個(gè)方法調(diào)用了一堆的EJB,如果每個(gè)EJB的調(diào)用都需要load balance,那么有可能會(huì)因?yàn)樾枰稚⒌讲煌姆?wù)器上進(jìn)行調(diào)用導(dǎo)致你的應(yīng)用崩潰,這樣的結(jié)果就是,你可能做了很多次無謂的跨服務(wù)器的調(diào)用。來看更糟糕的情況,如果你的方法是需要事務(wù)的,那么這個(gè)事務(wù)就必須跨越多個(gè)服務(wù)器,而這對(duì)于性能是會(huì)產(chǎn)生很大的損害的。

          共享資源和服務(wù)

          對(duì)于用于支撐并發(fā)請(qǐng)求的Java EE集群系統(tǒng)而言,其擴(kuò)展后的性能取決于對(duì)于那些不支持線性擴(kuò)展的共享資源的操作。數(shù)據(jù)庫(kù)服務(wù)器、JNDI樹、LDAP服務(wù)器以及外部的文件系統(tǒng)都有可能被集群中的節(jié)點(diǎn)共享。

          盡管Java EE規(guī)范中并不推薦,但為了實(shí)現(xiàn)各種目標(biāo),通常都會(huì)采用外部的I/O操作。例如,在我們實(shí)驗(yàn)室測(cè)試的應(yīng)用中有用文件系統(tǒng)來保存用戶上傳的文件的應(yīng)用,或動(dòng)態(tài)的創(chuàng)建xml配置文件的應(yīng)用。在集群內(nèi),應(yīng)用服務(wù)器節(jié)點(diǎn)必須想辦法來復(fù)制這些文件到其他的節(jié)點(diǎn),但這樣做是不利于擴(kuò)展的。隨著越來越多節(jié)點(diǎn)的加入,節(jié)點(diǎn)間的文件復(fù)制會(huì)占用所有的網(wǎng)絡(luò)帶寬和消耗大量的CPU資源。在集群中要達(dá)到這樣的目標(biāo),可以采用數(shù)據(jù)庫(kù)來替代外部文件,或采用SAN作為文件的集中存儲(chǔ),另外一個(gè)可選的方案是采用高效的分布式文件系統(tǒng),例如Hadoop DFS(http://wiki.apache.org/hadoop/)。

          在集群環(huán)境中共享服務(wù)很常見,這些服務(wù)不會(huì)部署到集群的每個(gè)節(jié)點(diǎn),而是部署在專門的服務(wù)器節(jié)點(diǎn)上,例如分布式的日志服務(wù)或時(shí)間服務(wù)。分布式鎖管理器 (DLM)來管理集群中的應(yīng)用對(duì)這些共享服務(wù)的同步訪問,即使在網(wǎng)絡(luò)延時(shí)和系統(tǒng)處理失敗的情況下,鎖管理器也必須正常操作。舉例來說,在我們的實(shí)驗(yàn)室中測(cè)試的一個(gè)ERP系統(tǒng)就碰到了這樣的問題,他們寫了自己的DLM系統(tǒng),最終發(fā)現(xiàn)當(dāng)集群中持有鎖的節(jié)點(diǎn)失敗時(shí),他們的lock system將會(huì)永遠(yuǎn)的持有鎖。

          分布式緩存

          我所碰到過的幾乎所有的Java EE項(xiàng)目都采用了對(duì)象緩存來提升性能,同樣所有流行的應(yīng)用服務(wù)器也都提供了不同級(jí)別的緩存來加速應(yīng)用。但有些緩存是為單一運(yùn)行的環(huán)境而設(shè)計(jì)的,并且只能在單JVM實(shí)例中正常的運(yùn)行。由于有些對(duì)象的創(chuàng)建需要耗費(fèi)大量的資源,我們需要緩存,因此我們維護(hù)對(duì)象池來緩存對(duì)象的實(shí)例。如果獲取維護(hù)緩存較之創(chuàng)建對(duì)象而言更劃算,那么我們就提升了系統(tǒng)的性能。在集群環(huán)境中,每個(gè)jvm實(shí)例維護(hù)著自己的緩存,為了保持集群中所有服務(wù)器狀態(tài)的一致,這些緩存對(duì)象需要進(jìn)行同步。有些時(shí)候這樣的同步機(jī)制有可能會(huì)比不采用緩存的性能還差,對(duì)于整個(gè)集群的擴(kuò)展能力而言,一個(gè)可擴(kuò)展的分布式緩存系統(tǒng)是非常重要的。

          如今很多分布式緩存相關(guān)的開源java產(chǎn)品已經(jīng)非常流行,在我們實(shí)驗(yàn)室中有如下的一些測(cè)試:

          • 1個(gè)基于JBoss Cache的項(xiàng)目的測(cè)試;
          • 3個(gè)基于Terracotta的項(xiàng)目的測(cè)試;
          • 9個(gè)基于memcached的項(xiàng)目的測(cè)試;
          測(cè)試結(jié)果表明Terracotta可以很好的擴(kuò)展到10個(gè)節(jié)點(diǎn),并且在不超過5個(gè)節(jié)點(diǎn)時(shí)擁有很高的性能,但memcached則在超過20個(gè)服務(wù)器節(jié)點(diǎn)時(shí)會(huì)擴(kuò)展的非常好。

          Memcached

          Memcached是一個(gè)高性能的分布式對(duì)象緩存系統(tǒng),經(jīng)常被用于降低數(shù)據(jù)庫(kù)load,同時(shí)提升動(dòng)態(tài)web應(yīng)用的速度。Memcached的奇妙之處在于它的兩階段hash的方法,它通過一個(gè)巨大的hash表來查找key = value對(duì),給它一個(gè)key,就可以set或get數(shù)據(jù)了。當(dāng)進(jìn)行一次memcached查詢時(shí),首先客戶端將會(huì)根據(jù)整個(gè)服務(wù)器的列表來對(duì)key進(jìn)行 hash,在找到一臺(tái)服務(wù)器后,客戶端就發(fā)送請(qǐng)求,服務(wù)器端在接收到請(qǐng)求后通過對(duì)key再做一次內(nèi)部的hash,從而查找到實(shí)際的數(shù)據(jù)項(xiàng)。當(dāng)處理巨大的系統(tǒng)時(shí),最大的好處就是memcached所具備的良好的水平擴(kuò)展能力。由于客戶端做了一層hashing,這使得增加N多的節(jié)點(diǎn)到集群變得非常的容易,并不會(huì)因?yàn)楣?jié)點(diǎn)的互連造成負(fù)載的增高,也不會(huì)因?yàn)槎嗖f(xié)議而造成網(wǎng)絡(luò)的洪水效應(yīng)。

          實(shí)際上Memcached并不是一款java產(chǎn)品,但它提供了Java client API,這也就意味著如果你需要在Java EE應(yīng)用中使用memcached的話,并不需要做多大的改動(dòng)就可以從cache中通過get獲取值,或通過put將值放入cache中。使用 memcached是非常簡(jiǎn)單的,不過同時(shí)也得注意一些事情避免對(duì)擴(kuò)展性和性能造成損失:

          • 不要緩存寫頻繁的對(duì)象。Memcached是用來減少對(duì)數(shù)據(jù)庫(kù)的讀操作的,而非寫操作,在使用Memcached前,應(yīng)先關(guān)注對(duì)象的讀/寫比率,如果這個(gè)比率比較高,那么采用緩存才有意義。
          • 盡量避免讓運(yùn)行的memcached的節(jié)點(diǎn)互相調(diào)用,對(duì)于memcached而言這是災(zāi)難性的。
          • 盡量避免行方式的緩存,在這樣的情況下可采用復(fù)雜的對(duì)象來進(jìn)行緩存,這對(duì)于memcached來說會(huì)更為有效。
          • 選 擇合適的hashing算法。在默認(rèn)的算法下,增加或減少服務(wù)器會(huì)導(dǎo)致所有的cache全部失效。由于服務(wù)器的列表hash值被改變,可能會(huì)造成大部分的 key都要hash到和之前不同的服務(wù)器上去,這種情況下,可以考慮采用持續(xù)的hashing算法(http://weblogs.java.net /blog/tomwhite/archive/2007/11/consistent_hash.html) 來增加和減少服務(wù)器,這樣做可以保證你大部分緩存的對(duì)象仍然是有效的。

          Terracotta

          Terracotta(http://www.terracottatech.com/)是一個(gè)企業(yè)級(jí)的、開源的、JVM級(jí)別的集群解決方案。JVM級(jí)的集群方案意味著可以支撐將企業(yè)級(jí)的Java應(yīng)用部署部署到多JVM上,而且就像是運(yùn)行在同一個(gè)JVM中。 Terracotta擴(kuò)展了JVM的內(nèi)存模型,各虛擬機(jī)上的線程通過集群來與其他虛擬機(jī)上的線程進(jìn)行交互(Terracotta extends the Java Memory Model of a single JVM to include a cluster of virtual machines such that threads on one virtual machine can interact with threads on another virtual machine as if they were all on the same virtual machine with an unlimited amount of heap.)。



          Figure 6: Terracotta JVM clustering


          采用Terracotta來實(shí)現(xiàn)集群應(yīng)用的編程方式和編寫單機(jī)應(yīng)用基本沒有什么差別,Terrocotta并沒有特別的提供開發(fā)者的API,Terracotta采用字節(jié)碼織入的方式(很多AOP軟件開發(fā)框架中采用的技術(shù),例如AspectJ和AspectWerkz)來將集群方式的代碼插入到已有的java語言中。

          我猜想Terrocotta是通過某種互連的方式或多播協(xié)議的方式來實(shí)現(xiàn)服務(wù)器和客戶端JVM實(shí)例的通訊的,可能是這個(gè)原因?qū)е铝嗽谖覀儗?shí)驗(yàn)室測(cè)試時(shí)的效果:當(dāng)超過20個(gè)節(jié)點(diǎn)時(shí)Terracotta擴(kuò)展的并不是很好。(注:這個(gè)測(cè)試結(jié)果僅為在我們實(shí)驗(yàn)室的測(cè)試結(jié)果,你的結(jié)果可能會(huì)不同。)

          并行處理

          我之前說過,單線程的任務(wù)會(huì)成為系統(tǒng)可擴(kuò)展性的瓶頸。但有些單線程的工作(例如處理或生成巨大的數(shù)據(jù)集)不僅需要多線程或多進(jìn)程的運(yùn)行,還會(huì)有擴(kuò)展到多節(jié)點(diǎn)運(yùn)行的需求。例如,在我們實(shí)驗(yàn)室測(cè)試的一個(gè)Java EE項(xiàng)目有一個(gè)場(chǎng)景是這樣的:根據(jù)他們站點(diǎn)的日志文件分析URL的訪問規(guī)則,每周產(chǎn)生的這些日志文件通常會(huì)超過120GB,當(dāng)采用單線程的Java應(yīng)用去分析時(shí)需要耗費(fèi)四個(gè)小時(shí),客戶改為采用Hadoop Map-Reduce使其能夠水平擴(kuò)展從而解決了這個(gè)問題,如今這個(gè)分析URL訪問規(guī)則的程序不僅運(yùn)行在多進(jìn)程模式下,同時(shí)還并行的在超過10個(gè)節(jié)點(diǎn)上運(yùn)行,而完成所有的工作也只需要7分鐘了。

          有很多的框架和工具可以幫助Java EE開發(fā)人員來讓應(yīng)用支持水平擴(kuò)展。除了Hadoop,很多MPI的Java實(shí)現(xiàn)也可以用來將單線程的任務(wù)水平的擴(kuò)展到多個(gè)節(jié)點(diǎn)上并行運(yùn)行。

          MapReduce

          MapReduce由Google的Jeffrey Dean和Sanjay Ghemawat提出,是一種用于在大型集群環(huán)境下處理巨量數(shù)據(jù)的分布式編程模型。MapReduce由兩個(gè)步驟來實(shí)現(xiàn) - Map:對(duì)集合中所有的對(duì)象進(jìn)行操作并基于處理返回一系列的結(jié)果,Reduce:通過多線程、進(jìn)程或獨(dú)立系統(tǒng)并行的從兩個(gè)或多個(gè)Map中整理和獲取結(jié)果。Map()和Reduce()都是可以并行運(yùn)行的,不過通常來說沒必要在同樣的系統(tǒng)同樣的時(shí)間這么來做。

          Hadoop是一個(gè)開源的、點(diǎn)對(duì)點(diǎn)的、純Java實(shí)現(xiàn)的MapReduce。它是一個(gè)用于將分布式應(yīng)用部署到大型廉價(jià)集群上運(yùn)行的Lucene-derived框架,得到了全世界范圍開源人士的支持以及廣泛的應(yīng)用,Yahoo的Search Webmap、Amazon EC2/S3服務(wù)以及Sun的網(wǎng)格引擎都可運(yùn)行在Hadoop上。

          簡(jiǎn)單來說,通過使用“Hadoop Map-Reduce”,"URL訪問規(guī)則分析"程序可以首先將日志文件分解為多個(gè)128M的小文件,然后由Hadoop將這些小文件分配到不同的Map()上去執(zhí)行。Map()會(huì)分析分配給它的小文件并產(chǎn)生臨時(shí)的結(jié)果,Map()產(chǎn)生的所有的臨時(shí)結(jié)果會(huì)被排序并分配給不同的Reduce(),Reduce()合并所有的臨時(shí)結(jié)果產(chǎn)生最終的結(jié)果,這些Map和Reduce操作都可以由Hadoop框架控制來并行的運(yùn)行在集群中所有的節(jié)點(diǎn)上。

          MapReduce對(duì)于很多應(yīng)用而言都是非常有用的,包括分布式檢索、分布式排序、web link-graph reversal、term-vector per host、web訪問日志分析、索引重建、文檔集群、機(jī)器智能學(xué)習(xí)、statistical machine translation和其他領(lǐng)域。

          MPI

          MPI是一種語言無關(guān)、用于實(shí)現(xiàn)并行運(yùn)行計(jì)算機(jī)間交互的通訊協(xié)議,目前已經(jīng)有很多Java版本的MPI標(biāo)準(zhǔn)的實(shí)現(xiàn),mpiJava和MPJ是其中的典型。mpiJava 基于JNI綁定native的MPI庫(kù)來實(shí)現(xiàn),MPJ是100%純java的MPI標(biāo)準(zhǔn)的實(shí)現(xiàn)。mpiJava和MPJ和MPI Fortran和C版本提供的API都基本一致,例如它們都對(duì)外提供了具備同樣方法名和參數(shù)的Comm class來實(shí)現(xiàn)MPI的信息傳遞。

          CCJ是一個(gè)類似MPI通訊操作的java庫(kù)。CCJ提供了barrier、broadcast、scatter、 gather、all-gather、reduce和all-reduce操作的支持(但不提供點(diǎn)對(duì)點(diǎn)的操作,例如send、receive和send- receive)。在底層的通訊協(xié)議方面,CCJ并沒有自己實(shí)現(xiàn),而是采用了Java RMI,這也就使得CCJ可以用來傳遞復(fù)雜的序列化對(duì)象,而不僅僅是MPI中的原始數(shù)據(jù)類型。進(jìn)一步看,CCJ還可以從一組并行的processes中獲取到復(fù)雜的集合對(duì)象,例如實(shí)現(xiàn)了CCJ的DividableDataObject接口的集合。

          采用不同的方法來獲取高擴(kuò)展能力

          有很多的書會(huì)教我們?nèi)绾我設(shè)O的方式來設(shè)計(jì)靈活架構(gòu)的系統(tǒng),如何來使服務(wù)透明的被客戶端使用以便維護(hù),如何采用正常的模式來設(shè)計(jì)數(shù)據(jù)庫(kù)schema以便集成。但有些時(shí)候?yàn)榱双@取高擴(kuò)展性,需要采用一些不同的方法。

          Google設(shè)計(jì)了自己的高可擴(kuò)展的分布式文件系統(tǒng)(GFS),它并不是基于POSIX API來實(shí)現(xiàn)的,不過GFS對(duì)于用戶來說并不完全透明。為了使用GFS,你必須采用GFS的API包。Google也設(shè)計(jì)了自己的高可擴(kuò)展的分布式數(shù)據(jù)庫(kù)系統(tǒng)(Bigtable),但它并不遵循ANSI SQL標(biāo)準(zhǔn),而且其中的概念和結(jié)構(gòu)和傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)幾乎完全不同,但最重要的是GFS和Bigtable能夠滿足Google的存儲(chǔ)要求、良好的擴(kuò)展性要求,并且已經(jīng)被Google的廣泛的作為其存儲(chǔ)平臺(tái)而使用。

          傳統(tǒng)方式下,我們通過使用更大型的、更快和更貴的機(jī)器或企業(yè)級(jí)的集群數(shù)據(jù)庫(kù)(例如RAC)來將數(shù)據(jù)庫(kù)擴(kuò)展到多節(jié)點(diǎn)運(yùn)行,但我有一個(gè)我們實(shí)驗(yàn)室中測(cè)試的social networking的網(wǎng)站采用了不同的方式,這個(gè)應(yīng)用允許用戶在網(wǎng)站上創(chuàng)建profiles、blogs,和朋友共享照片和音樂,此應(yīng)用基于Java EE編寫,運(yùn)行在Tomcat和Mysql上,但不同于我們實(shí)驗(yàn)室中測(cè)試的其他應(yīng)用,它只是希望在20多臺(tái)便宜的PC Server上進(jìn)行測(cè)試,其數(shù)據(jù)模型結(jié)構(gòu)如下:


          Figure 7: Users data partitions


          這里比較特殊的地方子礙于不同的用戶數(shù)據(jù)(例如profile、blog)可能會(huì)存儲(chǔ)在不同的數(shù)據(jù)庫(kù)實(shí)例上,例如,用戶 00001存儲(chǔ)在服務(wù)器A上,而用戶20001存儲(chǔ)在服務(wù)器C上,分庫(kù)的規(guī)則以一張?jiān)畔⒌谋淼姆绞酱鎯?chǔ)在專門的數(shù)據(jù)庫(kù)上。當(dāng)部署在Tomcat的 Java EE應(yīng)用希望獲取或更新用戶信息時(shí),首先它會(huì)從這張?jiān)畔⒌谋碇蝎@取到需要去哪臺(tái)服務(wù)器上獲取這個(gè)用戶,然后再連到實(shí)際的服務(wù)器上去執(zhí)行查詢或更新操作。

          用戶數(shù)據(jù)分區(qū)和這種兩步時(shí)的動(dòng)作方式可以帶來如下的一些好處:

          • 擴(kuò)展了寫的帶寬:對(duì)于這類應(yīng)用而言,blogging、ranking和BBS將會(huì)使得寫帶寬成為網(wǎng)站的主要瓶頸。分 布式的緩存對(duì)于數(shù)據(jù)庫(kù)的寫操作只能帶來很小的提升。采用數(shù)據(jù)分區(qū)的方式,可以并行的進(jìn)行寫,同樣也就意味著提升了寫的吞吐量。要支持更多的注冊(cè)用戶,只需 要通過增加更多的數(shù)據(jù)庫(kù)節(jié)點(diǎn),然后修改元信息表來匹配到新的服務(wù)器上。
          • 高可用性:如果一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器down了,那么只會(huì)有部分用戶被影響,而其他大部分的用戶可以仍然正常使用;
          同時(shí)也會(huì)帶來一些缺點(diǎn):
          • 由于數(shù)據(jù)庫(kù)節(jié)點(diǎn)可以動(dòng)態(tài)的增加,這對(duì)于在Tomcat中的Java EE應(yīng)用而言要使用數(shù)據(jù)庫(kù)連接池就比較難了;
          • 由于操作用戶的數(shù)據(jù)是兩步式的,這也就意味著很難使用ORMapping的工具去實(shí)現(xiàn);
          • 當(dāng)要執(zhí)行一個(gè)復(fù)雜的搜索或合并數(shù)據(jù)時(shí),需要從多臺(tái)數(shù)據(jù)庫(kù)服務(wù)器上獲取很多不同的數(shù)據(jù)。

          這個(gè)系統(tǒng)的架構(gòu)師這么說:“我們已經(jīng)知道這些缺點(diǎn),并且準(zhǔn)備好了應(yīng)對(duì)它,我們甚至準(zhǔn)備好了應(yīng)對(duì)當(dāng)元信息表的服務(wù)器成為瓶頸的狀況,如果出現(xiàn)那樣的狀況我們將會(huì)把元信息表再次劃分,并創(chuàng)建出一個(gè)更高級(jí)別的元信息表來指向眾多的二級(jí)元信息表服務(wù)器實(shí)例。“

          參考

          1. Scalability definition in wikipedia: http://en.wikipedia.org/wiki/Scalability
          2. Javadoc of atomic APIs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html
          3. Alan Kaminsky. Parallel Java: A unified API for shared memory and cluster parallel programming in 100% Java: http://www.cs.rit.edu/~ark/20070326/pj.pdf
          4. OMP-an OpenMP-like interface for Java: http://portal.acm.org/citation.cfm?id=337466
          5. Google MapReduce white paper: http://labs.google.com/papers/mapreduce-osdi04.pdf
          6. Google Bigtable white paper: http://labs.google.com/papers/bigtable-osdi06.pdf
          7. Hadoop MapReduce tutorial: http://hadoop.apache.org/core/docs/r0.17.0/mapred_tutorial.html
          8. Memcached FAQ: http://www.socialtext.net/memcached/index.cgi?faq
          9. Terracotta: http://www.terracotta.org/

          關(guān)于作者

          Wang Yu目前在Sun的ISVE Group小組工作,擔(dān)任的職位為Java工程師和架構(gòu)咨詢師,他承擔(dān)的職責(zé)包括支持本地的ISVs,為一些重要的Java技術(shù)例如Java EE、EJB、JSP/Servlet、JMS和web services技術(shù)提供咨詢,可以通過wang.yu@sun.com聯(lián)系他。
          posted on 2008-07-10 19:36 CONAN 閱讀(220) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE
          主站蜘蛛池模板: 北川| 原阳县| 永年县| 永靖县| 雷波县| 瑞安市| 德昌县| 西贡区| 威海市| 阆中市| 陈巴尔虎旗| 门头沟区| 淄博市| 弥勒县| 通渭县| 中超| 万全县| 富蕴县| 奎屯市| 永德县| 屏东市| 勐海县| 竹溪县| 福清市| 岳普湖县| 兰州市| 蕲春县| 深水埗区| 荆州市| 清苑县| 安阳县| 墨江| 泰顺县| 汕头市| 大同市| 新巴尔虎左旗| 通化市| 新沂市| 文登市| 广水市| 凤凰县|