對雲計算中幾種基礎設施(Dynamo,Bigtable,Map/Reduce等)的樸素看法

前言
    雲計算的概念近期可謂如火如荼,備受關注。我先前聽到“雲”這個名詞時,很是覺得太過玄乎——也不知道它用在哪裏,更不瞭解它如何實現,總有霧裏看花的感覺!

    好在近期工作需要的緣故,學習和開發過類似於“雲計算”基礎設施的內部系統,之後再回過頭來看看業界兩大寡頭(Google,Amazon)推出各自的雲計算服務,從認識上纔算是真的將“雲”這個天書般的概念落實。後面的文章中我將在個人理解的基礎上,針對雲計算的概念,體系結構,以及適用性等方面作一些不算很深入分析和對比,希望對大家理解雲計算架構有所幫助。

 

第一部分 什麼是雲計算
    雲計算的標準定義留給大家去Google吧,我這裏談談我簡化理解後的雲計算是什麼東東:先來看雲計算的產生原因吧!——首要原因是爲了應對待處理數據爆炸式增長與當今機器存儲能力和計算能力不足之間的矛盾(借用一下我國當前基本矛盾的書法:)。由於待處理數據越來越多(不是用多少G就能描述的範疇了。想象一下假若要存儲並計算數千萬用戶的訪問日誌,或者計算數億個網頁的Page Rank),多到了很難在一臺或有限數目的存儲服務器內容納,且更無法由一臺或數目有限的計算服務器就能處理這樣的海量數據。—— 當然,你也許會想到買來漂亮的EMC存儲陣列和HP的SUPERSTONE這樣的小型機搞定一切,但是它們有點貴嘍,這種砸錢的大傢伙只能留給闊綽的銀行、電信企業,或者國家氣象局這些機構使用了—— 這時就需要能在普通機器(比如在中關村攢出的廉價PC)上分佈式的存儲這些數據,並能在其上分佈式計算這些數據。你肯定會說,這不久是分佈計算嗎?沒錯,雲計算可以說是經分佈計算,並行計算,網格計算一脈相承的技術路線,甚至可以說它們基因相同。但它們的給人的外貌卻不同,這是因爲雲計算是經過商業包裝的名詞,其實就是將分佈存儲和分佈計算這種技術找了個盈利模式——將存儲能力和計算能力出售給第三方企業。而第三方不需知道其數據到底存在那個機器上,也不需要知道那個機器在處理它們的數據,因此對它們來說數據在雲端,計算也在雲端,大約如此,纔有了“雲計算”這個概念。

目前出售雲計算服務的有Amazon和Google兩個業界老大(聽說Oracle和APPLE也開始搞了,EMC似乎也有計劃),出售的服務內容大體相同,盈利方式也大同小異(具體參看他們的網站的S3服務, EC2服務,或Google App Engine服務等)。它們技術架構雖有差異,但從概念上講可把雲計算看成是“存儲雲”結合“計算雲”的有機結合,即“雲計算 = 存儲雲 + 計算雲”

 

第二部分 存儲雲的架構介紹
存儲雲概念
    存儲雲依我看就是一個被商業包裝過的分佈存儲系統——只不過它對第三方用戶公開存儲接口,用戶可買容量和帶寬,且規模相當宏偉的分佈存儲系統。關於商業模式問題我們就不多作探討了,大家可到其網站上仔細瞧瞧。我這裏的重點是對用於存儲雲的分佈存儲系統作對比分析。(不過假如你對存儲雲完全不瞭解,那我建議在看下面內容之前,先去讀讀相關的論文什麼的介紹吧!以便我們的討論事半功倍。)

存儲雲結構比較——Dynamo VS Bigtable
    比較典型的存儲雲基礎系統有Amazon公司的Dynamo系統與Google公司的Bigtable系統,這兩種系統不但已經開始是商用(參見S3 服務和 Google App Engine服務),而且都公開了比較詳細的實現論文(尤其dynamo系統論文格外詳盡——可見Amazon公司的無私和自信)。它們各自實現架構迥異,存儲特性不一,但都結構優美,技術上各有可稱道的地方,可謂各有千秋,卻又殊途同歸。

下面我們將針對它們兩者存儲數據的要求、體系架構、擴容、負載均衡、容錯、數據存取及查詢等我覺得重要的方面進行一些點到爲止分析比較,以辨明良莠。

數據結構化問題
    首先要提到的是兩者存儲數據屬性上的區別,雖然兩者都是以key/value形式進行存儲,但Dynamo偏向存儲原數據,因爲其所存儲的數據是非結構化數據,對value的解析完全是用戶程序的事情,Dynamo系統不識別任何結構數據,都統一按照binary數據對待;而Bigtable存儲的是結構化或半結構化數據(web數據特點就是介於結構化和非結構化之間,因此稱爲半結構化數據。我這裏不展開說它了,不瞭解半結構化數據的趕緊去google一下吧!),其value是有結構的數據——就如關係數據庫中的列一般,因而可支持一定程度的Query(比如可按單列進行)。這點上看Bigtable更接近數據庫(接近而不是等價!至於和關係數據庫的具體區別可去google 一下,網上論述可不少!);另外, Bigtable所存儲的數據都是以字符串格式實現,所以對主建或者列(以及其自動加上的時間戳)排序都是以字符序進行,而dynamo的鍵值並非以字符串存儲,而是統一經過md5算法轉後成16字節md5_key存儲的,因此對數據的訪問必須知道key纔可進行,故而對掃表(用遊標)或者query訪問則無能爲力。當然在dynamo的基礎上,配合一些方式我們實現query也並不可能,一些具體方式我們後面慢慢探討!

控制與存儲架構比較
   Dynamo是採用DHT(分佈哈希表,請參看有關資料吧)作爲基本存儲架構和理念,這個架構最大特點是能讓數據在環中“存儲”均勻,各存儲點相互能感知(因數據需要在環內轉發,以及相互之間進行故障探測,因此需要節點之間的通訊),自我管理性強,因爲它不需要Master主控點控制,有點是無熱點,無單點故障危險——插一句,目前新浪的memcachedb(改造memcached,增加了持續化能力)其實可認爲是這種架構的最簡單代表(數據進入系統後,使用DHT算法均勻的發送到存儲節點上,而最後存儲引擎採用Berkelery DB,將數據持續化到本地硬盤)。

   Bigtable的控制是採用傳統的server farm形式,使用一個主控服務器+多個子表服務器構成。而數據存儲形式是採用多維Map的稀疏結構,可看成是由多個列表組成,所謂稀疏是說每條記錄並非要求有全列。其數據(包括索引,日誌,記錄數據)最終是存儲在分佈文件系統DFS之上——數據被以DFS所特有的文件形式分佈存儲在各各節點之上。相比DHT的存儲環自管理技術,它需要有master主控服務器來負責監控各客戶存儲節點(分配子表,失效檢測,負載均衡等),另外索引文件的根也是集中存儲,需要客戶端首先讀取(之後可以採用預讀和緩存的技術減少讀取索引表的次數)。這種集中控制的做法有一個缺陷就是系統存在單點故障 —— 因此單點需要高可用性,如記錄恢復日誌或雙機備份等——但好處是更人爲可控,方便維護,且集中管理時數據同步易於方便——顯然,更新集中存儲的原數據(如數據索引或節點路由等)相比DHT環中各個節點存儲的原數據(如membership,即各點的路由關係)需要利用“閒談機制”依次通知式地進行漸近更新要容易許多。

 

容錯問題
    Dynamo和Bigtable都不是實驗室應付領導參觀,或者是炫耀技術的Demo,而是要實實在在進行商業運營的產品,因此首先要考慮的是機器成本問題!最節約的方式就是採用普通PC服務器(目前市場價格大約2/3千元就能買到存儲1T數據的機器——自然是沒有顯示器,聲卡這些外設的)作爲存儲機器。但做過大數據處理的人都知道,IDE/STAT硬盤的穩定性和壽命是無法和真正服務器中的SCSI硬盤相媲美(除硬盤外的其餘部件的穩定性和壽命也一樣和服務器差距頗大),在壓力下損壞那是家常便飯——據Google說,1000臺機器的集羣中,平均每天壞掉一臺機器——因此設計之初就將硬件故障認爲是常態的,也就是說容錯成爲設計優先考慮的問題了。

    鑑於上述原因,Dynamo和Bigtable的數據都是冗餘存放,也就是說一份數據會被複製成數份(副本數是可以根據數據要緊程度指定的),並被分散放在不同的機器上,以便發生機器宕機(偶然性宕機或網路不通屬於臨時故障,而硬盤壞掉則是永久故障,永久故障需要進行故障恢復——從副本恢復數據)時還有可用副本可繼續提供服務——通常存放三個副本就已經可以高枕無憂了,因爲要知道三個副本同期壞的可能性小到了1000*1000*1000分之一。

     Dynamo 的冗餘副本讀寫策略比較有趣,它定義了:N,W,R三個參數。其中N代表系統中每條記錄的副本數,W代表每次記錄成功寫操作需要寫入的副本數,R代表每次記錄讀請求最少需要讀取的副本數。只要W+R >N就可以保證數據的一致性。因爲W+R>N時讀寫總會有交集——必定最少有W+R-N個讀請求會落到被寫的副本上,所以必然會讀到“最後”被更新的副本數據(至於誰
“最後”的判斷需採用時間戳或者時鐘向量等技術完成——有邏輯關係先後由時鐘向量判斷,否則簡單的用時間戳先後判斷.詳情去看dynamo論文吧)。這種做法相比我們最樸素的想法——我們直觀的想法一定認爲如果系統要求記錄冗餘N份,那麼每次就寫入N份,而在讀請求時讀取任意一份可用記錄即可——要更安全,也更靈活。說其更安全是指數據一致性更能被保證:比如說客戶寫入一條記錄,該記錄有三個副本在三個不同點上,但是其中一個點臨時故障了,因此記錄沒有被寫入/更新。那麼在對該記錄再讀取時,如果取兩點(R=2)則必然會讀取到最少一個正確的值(臨時故障點有可能在讀是恢復,那麼讀出的值則不存在或者不是最新的;若臨時故障點還未恢復,則讀請求無法訪問其上副本)。而使用我們傳統方法可能讀到發生臨時故障的那點,此刻就有可能讀出現錯誤記錄(舊的或者不存在),因此可以看到加大W,R可提高系統安全性;說其更靈活則是指可通過配置N,W,R這幾個參數以滿足包括訪問方式、速度和數據安全等迥異需求的各種場景:比如對於寫多讀少的操作,可將W配低,R配高;想法對於寫少讀多的操作,則可將W配高,R配低。

    Bigtable的容錯問題論文中沒有詳細講,我想它應該是將該任務交給其下的DFS處理了:DFS是在文件chunk(64M)寫入chunk服務器時,將數據chunk傳播給最近的N-1個chunk服務器,從而確保了系統中每個chunk存在多個副本,而這些chunk 的位置信息都會記錄在master服務器的文件原數據中。再訪問文件時,會先獲得原數據,再從可用的chunk服務器中獲取數據,因此一個chunk server發生故障不影響數據完整性,照樣能讀。另外DFS的故障的恢復等工作也是在master服務器監控下將某個副本chunk進行復制,以恢復故障機器上的數據副本。

    最後值得提一下的是,Dynamo對於臨時故障的處理方式是:找到一臺可用機器,將數據暫時寫到其上的臨時表中,待臨時故障恢復後,臨時表中的數據會自動寫回原目的地。這樣做得目的是達到永遠可寫(那怕該雲中只有一臺機器可用,那麼寫請求的數據就不會丟失)。這個需求未見Bigtable提到,但從其架構上看DFS對寫操作來說,應該也是能達到接近Dynamo的永遠可寫需求的(master會幫助選擇一個可寫的chunk server 作爲寫請求的接受者的,因此係統只要master不可用,最少再有一臺可用chunk server機器就以滿足。

 

擴容問題
    對於一個存儲可視爲無限大的存儲系統來說,擴容需求(擴容需求除了存儲容量不足外,存儲節點併發處理能力不足,也會要求擴容)自然無法逃避,而且對於在線服務系統擴容時期要儘量不停止服務或者儘可能短的停止服務,因此優美的擴容方案是存儲雲中最值得關注的要點之一。

    我們還是先來說說Dynamo系統的擴容策略和實現。試想一下,將一個機器中的指定數據表擴容,首先需要將這個數據表劈開成兩個表,然後再把其中一個轉移到另外一臺新機器上去。而這裏的劈表動作說起簡單,作起來則頗爲費力,因爲無論數據表是按照鍵值區間有序組織(如DHT環方式),或鍵值本身有序組織(如Bigtable方式),都不可避免的需要掃描整個數據表(特耗資源的操作,絕對會影響其他服務的)才能從中挑選出一部分有序數據移到新表中,從而保證劈開後的兩個表仍然維持有序結構。爲了避免笨拙的掃表工作,Dynamo取巧了,它會將md5 key所圍成的環行區間,儘量劃分的粒度細一些,也就是多分成一些較小的區間/段(一個段對應存在硬盤上的一個數據表),但是要求一個物理機器不只存儲一個段,而是存儲連續區間的一組段表,這樣以來在擴容時就能將劈大表的操作給迴避了。比如將環分成1024段(存儲數據上規模時,實際部署時段表要分的更細緻得多),然後又規定每個存儲點維護64個段表,那麼全部數據起先可部署在 16個機器的存儲環上。如果發現某個機器存儲不下64個段表時(或者承受不了當前的併發請求量時),則將其中部分段錶轉移到新擴容的機器上去即可,比如從原機器上轉移32個段表拷貝到新機器即可完成擴容——這種小表遷移避免了對大表拆分時的掃表、劈表動作。當然你會說這種擴容有限制,只能擴容6次。沒錯,因此在實際存儲環之初,是需要估計數據總量,擴容次數等問題的,但這絕對得。  

    Dynamo除了段表思想值得學習外,還提出了擴容期間不停服務這種要求很是可愛。我們也嘗試過這種高可用性擴容設計,其主要任務是要理清楚,從而細緻處理擴容期間(包括數據擴容和路由更新)的訪問請求的狀態機。另外要說的是擴容時爲了不影響正常請求訪問, 都將擴容例程安排在低優先級進行, 讓它在正常讀寫請求壓力小時再偷偷進行!

    對於Bigtable擴容問題Google本身的論文描述有些曖昧,但卻可在另一個類Bigtable系統——hypertable——那裏看到比較清晰的說法。Hypertable是Bigtable的開源C++實現。由於Hypertable中記錄存儲是被集合成固定大小的tablet(默認的最大值是每個200M)存在DFS上——而DFS本身具有可擴容性(允許在線添加新機器到server farm中)—— 因此Hypertable存儲總空間的擴容不存任何問題。其要作的只是當子表(Range段)過大時,需要將其從中間key 劈開成兩個新表,把包含後半段key範圍的新字表遷移到別的range server上去。注意這種分子表的實現路數似乎仍然需要去掃描表,在這一點上我個人認爲不如Dynamo做的聰明、利索。關於hypertable的表的管理值得大家去留心,但這裏不多說了。(請看hyptertable 站點:http://www.hypertable.org/documentation.html/)

 

負載均衡問題
    負載均衡(意義在於數據存儲均衡和訪問壓力均衡)對於Dynamo系統而言是天生的優勢,因爲它採用了DHT方式將數據都均勻存儲到各個點了,所以沒有熱點在(或者說要熱,則環中所有的點一起熱),各點的數據存儲量和訪問壓力應該都是均衡的(這點由md5算法特性決定)。 另外這裏還要提一下Dynamo系統中的Virtual Node概念——VNODE 可看成一個資源容器(類似於虛擬機),存儲作爲一個服務運行於其中。引入VNODE 目的在於將資源管理粒度單元化。 比如一個VNODE 讓你且只讓你管理5G硬盤,500M內存等,那麼你就只能使用這麼多資源。這樣有兩個顯而易見的好處:1 方便管理不同配置的異構機器,比如資源多的機器多部署一些VNODE ,而資源少的機器少不部署一些VNODE 。 2 對於擴容大有好處,因爲DHT環中加入一個新節點,如果想保持數據均勻分佈的特性,那麼必須將全環的數據都要移動纔有可能,這樣無疑增加了網絡震盪,因此最理想的方式是在環內每個點都進行擴容,這樣就只需要移動旁邊節點的數據了。那麼單增加一個或幾個機器顯然不能均勻分配環的其他存儲點旁,因此需要將一臺物理機器劃分成衆多個VNODE ,這樣纔有可能能將這些VNODE 比較均勻的散佈在環內其他節點旁了。隨着逐步添加機器,那麼數據均勻性逐步提高,可見這是一種逐漸式的數據均衡過程。

     對於Bigtable的負載均衡是也是基於傳統上server farm :依靠一個master服務器監視子表 server的負載情況,根據所有子表服務器的負載情況進行數據遷移的,比如將訪問很熱的列表遷移到壓力輕的子表服務器上(數據最終還是落在了chunk server —— DFS上的存儲服務點,從層級結構上來說處於子表服務器之下)。具體做法你可參見他們的論文,總的來說有沒有太多創新。

 

數據存取和查詢問題
    Dynamo和Bigtable兩種體系都支持key/value形式的記錄插入,而且也支持主建的隨機查詢。不過前面已經提到了如果需要按照列進行查詢,或者需要range的query查詢,則Dynamo就無能爲力了,只能使用Bigtable架構(但要知道Bigtable並沒有關係數據那麼強,對於query的支持也僅僅是支持條件是單個列,不能以多列爲目標進行復合條件查詢,更別說join查詢等)。從這點上說bigtable更接近數據庫,而Dynamo則是一個簡單的存儲系統。

    amazon在S3(可能部分利用了Dynamo)之後,推出了支持query的Simpledb 系統。 該系統和Bigtable很類似,但似乎功能更強,它支持=, !=, <, > <=, >=, STARTS-WITH, AND, OR, NOT, INTERSECTION AND UNION等複雜的query 操作。這真是個出色的產品,不幸的是amazon並沒有向對Dynamo那樣慷慨的公開發表其實現的論文,因此大家只能猜測其實現,有的說是在Erlang上重寫的,有的說在Dynamo基礎上開發的,有的說是拋開Dynamo全新實現的,目前說法衆多,無從得知。這裏我僅僅就我個人的認知,談談假如在Dynamo上是如何實現Query功能類似的功能。

    首先能想到的是爲Dynamo增加schema,也就是將value劃分成邏輯列,這樣以來在存儲時可以按列建立索引文件,那麼就自然可以實現對列的 query。索引文件內容可以是列值到主建集合的映射,其存儲以文件形式存在於分佈文件系統之上。當對列進行query時,首先在索引文件中找到對應的主建集合,然後在以主建從Dynamo中獲得記錄。不過這樣作有一定限制: 1 分佈文件系統需要能支持併發修改文件能力(因爲索引文件需要頻繁改變),而大多數分佈文件系統爲了數據一致性和效率的考慮,都只能支持併發追加操作,因此要想實時的完成數據更新的同時支持查詢操作有難度——簡單的方法是定期更新索引文件,那麼副作用就是查詢的結果不是最新的;2 只能對預先建立索引的單列進行排序(當然可以建立聯合索引),並不能支持對任列,或者任意的複合條件完成query查詢——我是沒想到什麼好辦法。

    另外一個方法是使用關係數據庫作Dynamo的存儲引擎——如果你看過Dynamo的論文,可否記得它提到了實際的存儲引擎可使用Berkelery DB或者mysql等——,那麼在存儲環中進行查詢的操作可化整爲零:將查詢任務路由到各各存儲節點上分別進行查詢之後,再將結果收集起來,對於需要排序的請求則還要再集中進行排序一次。這種做法把索引等等的工作都交由關係數據庫去作,我們作的只是需要彙總結果。 在這個思路上可以進一步結合數據分發Partition策略:不再按照md5 key那樣在節點上均勻的存放數據,而是按照列作partition 篇分發數據,如地址屬性中的Beijing,xi an等不同地名的數據路由到指定不同節點上,那麼在按地名進行查詢時,則可以直接將請求下發到對應存儲節點,這樣避免了全環下發查詢人物,能更有效的完成以列爲條件的複雜查詢。除此外,還可以對列進行區間排序partation,如對年齡列,按照0-10歲一個區間,10-20一個區間,20-30一個區間,而每個區間存儲在不同節點上,這種有序區間部署方法可支持按列排序查詢要求。不過有得必有失,partition存放的缺點是數據不夠均勻,因此負載不平衡,所以需要能把partation節點縱向擴容,比如把負責20-30區間的存儲節點多搞幾個以分擔併發壓力。

 

第三部分 當前計算雲的架構實現
    存儲雲的商業模式是出賣存儲能力,而計算雲的商業模式是出賣計算能力。存儲雲的基礎技術是分佈存儲,而計算雲的基礎技術是分佈計算——更準確說在是“並行計算“。 並行計算的作用是將大型的計算任務拆分,然後再派發到雲中的節點進行分佈式的並行計算,最終再將結果收集後統一整理(如排序、合併等)。 如果說雲計算雲是並行計算的昇華的話,那麼只在一個層面上有所進步 —— 計算資源虛擬化:計算雲中的所有計算資源都被看成一個可分配和回收的計算資源池,用戶可根據自己的實際需求購買相應的計算資源。

    這種資源虛擬化得益於近日重新興起的虛擬機技術,採用虛擬機實現資源的虛擬化,既可以避免了硬件異構的特性(無論什麼樣的硬件機器主要攢在一起,其計算資源都可被量化到計算資源池中,並被動態分配),更可以實現資源的動態調整,因此能極大的節約了雲中的計算資源(動態調整就是不需要重新啓動系統就可調整資源大小,這是虛擬化技術的最大用處之一)。這種虛擬化和我們在自己機器上安裝的虛擬機所採用的虛擬化技術大同小異,其異處就在於我們個人用戶的使用模式是將一臺物理機器的資源虛擬化成多份,以使得其能同時啓動多個操作系統;而云中的虛擬化技術是將多個物理機器的資源虛擬化成一個大的資源池,讓用戶感覺是一個巨大資源的機器——但是要知道只有任務在能並行計算的前提下,資源池虛擬化纔有意義。比如用100個386機器組成的計算雲可以處理1T的日誌數據,如果日誌數據的處理可以被並行進行,那麼可讓每個386機器都處理1/100T的數據,最後將所有中間結果合併成最後結果。但是如果任務無法平行差分,再大的計算池也沒用(雲計算應用是有限的,目前最能用的上的是web網站——數據量大,但處理相對簡單)。

    總而言之:計算雲的架構可以看成是:並行計算+ 資源虛擬化。

 

並行計算架構(Map/Reduce)
    對於資源虛擬話的問題,這裏不作討論了,有機會我們專門起個話題進行深入探討。這裏主要說說雲中的並行計算方式。並行計算是個老話題了,很多基於MPI的並行計算軟件處處可見。MPI採用任務之間消息傳遞方式進行數據交換,其並行開發基本思路是將任務分割成可以獨立完成的部分,再下發到各計算節點分別計算,計算後各節點將各自的結果彙總到主計算點進行最終彙總,各點之間的的交互由消息傳遞完成。對於並行計算面臨的主要問題是: 1 算法是否可以劃分成獨立部分;2 獲取計算數據以及中間結果存儲代價很高,因爲海量數據的讀取會帶來沉重的IO壓力——如在處理諸如page rank等互聯網應用上,很大程度上大量、頻繁的讀取分佈存儲的網頁數據造成了任務計算速度的瓶頸。

    對於第一個算法問題,從計算架構上考慮勉爲其難,關鍵在於分割算法。而對於第二個IO壓力問題,最好的解決辦法莫過於Hadoop項目項目所用的Map/Reduce方式,其思想很簡單,就是將計算程序下發到數據存儲節點,就地進行計算,從而避免了在網絡上傳輸數據的壓力。這並非一個創新思想,很久之前就有諸多嘗試(比如IBM曾經搞國一個叫Aglet的移動代理項目,就是將計算程序下發到各節點計算和收集信息),但對於海量數據處理的今天這種方式無疑最具吸引力,代價最小。

    簡單說Map是一個把數據分開的過程,Reduce則是把分開的數據合併的過程。如Hadoop的word count例子:用Map把[one,word, one,dream]進行映射就變成了[{one,1}, {word,1}, {one,1}, {dream,1}],再用Reduce把[{one,1}, {word,1}, {one,1}, {dream,1}]歸約變成[{one,2}, {word,1}, {dream,1}]的結果集。 關於Map/Reduce的抽象方法是map/recduce的精髓之一,但本文不多說它了(你可參看函數語言或其他種種資料,這裏不在贅述),本文主要想談談Map 的數據來源問題。

 

MAP/REDUCE數據來源
    Map 的數據來源初看也並非什麼問題,無非就是讀本地數據而已(前面已經說過計算程序作爲map的回調算子——借用java的說法——被轉移到了數據所在地再執行)。然而具體在海量數據處理的應用場景下就必須考慮和分佈存儲系統搭配了。 Hadoop的搭配方式最簡單,就是和其下的分佈文件系統DFS配合: 通過文件系統的原數據來定位文件塊的分佈節點位置,然後將回調算子下發到其上,已順序讀取的方式從本地文件系統上讀取數據。對於日誌文件分析等應用,上述做法效率很高,因爲日誌文件讀取可是順序讀取,文件系統的預讀特點可充分利用 —— 離線日誌分析是利用map/reduce分析的典型應用。

    但我們也應看到Map/Recduce 的使用也有明顯的侷限性:第一是,如果對於較爲複雜的輸入要求,比如需要對數據集合進行query查詢,而非順序讀取文件的輸入,則不能直接使用Hadoop的Map/Recduce框架;第二是,其下的分佈文件系統爲了一致性考慮,不支持多個併發寫,而且寫後不能修改,這些特性對日誌等事後分析效果不錯,但對於數據需要實時產生的場景有些勉爲其難了。因此考慮是否能將Dynamo,甚至是Bigtable等分佈存儲系統或者分佈類數據庫系統在Map/Recduce環境下使用便成了新的需求。不過我感覺Bigtable的存儲結構似乎不大容易實現在本地環境內完成進行較爲複雜的查詢(比如多列的符合查詢,不一定能完成,且更不容易在本地完成——應爲它無法避免到遠程取數據,而如果一旦跨機器進行查詢則又帶來了過多的網絡I/O,違背了Map/Reduce架構進行並行計算的設計初衷。那麼Dynamo是否可滿足負責query需求呢? 如果採用上文在查詢時提到的方法:給記錄定義對應的schema,並存儲在存儲點上將其存在傳統的關係數據庫中(可以在需要列上建立索引),那麼將“回調算子——這裏就是query語句了”下發到其上,則可按照傳統方式在本地進行query!這樣以來既符合了Map/Reduce的初衷,又能滿足複雜輸入需求,同時還能不影響數據的實時產生。因此我認爲靈活、方便的並行計算架構可以由Dynamo或其變種存儲系統(如上文所說的partition方式)+ Map/Reduce完成。

 

 

當前幾種雲計算架構中的明星系統
    目前雲計算中的各種子系統可謂風起雲涌,層出不窮。我這裏簡單提及幾個我瞭解過的項目,大家有興趣的話可重點跟蹤它們,近一步瞭解雲計算知識。

1 Bigtable /Dynamo 上文已經講過了。

2 Hbase 是Hadoop的一個子項目,類似於Bigtable , 最適合使用Hbase存儲的數據是非常稀疏的數據(非結構化或者半結構化的數據)。Hbase之所以擅長存儲這類數據,是因爲Hbase和Bigtable一樣,是列導向的存儲機制 
3 Couchdb 是Apache下的一個面向文檔存儲,由Erlang開發而成,和其他新型存儲系統一樣它同樣是分佈存儲系統,具有很好的擴展性。但不同在於沒有任何統一的schema可言,數據組織是平坦的,無行無列。如果需要查詢等操作,則藉助於用戶自己提供的聚合與過濾算子,以Map/Reduce方式進行對文檔信息進行全文檢索處理——這個角度上說它也能實現類似數據庫的查詢,可方式方法完全不同——但它提供了一個view的數據關係邏輯接口,對用戶而言,可以想象成傳統的表。

4 Simpledb 是amazon公司開發的一個可供查詢的分佈數據存儲系統,它是Dynamo鍵值存儲的補充和豐富,目前用在其雲計算服務中。其具體實現方式沒有論文公開。

5 Pig 是yahoo捐獻給apache的一個很有趣項目,它不是一個系統,而是一個類SQL語言, 具體目標是在MapReduce上構建的一種高級查詢語言。目的是把一些運算編譯進MapReduce模型的Map和Reduce中,允許用戶可以自己的功能. Pig支持的很多代數運算、複雜數據類型(tuple,map)、統計運算(COUNT,SUM,AVG,MIN,MAX)和相關數據庫檢索運算(FILTER,GROUP BY,ORDER,DISTINCT,UNION,JOIN,FOREACH ... GENERATE)

 

 

 

結束語: 
    我瞭解的差不多就這麼多了。要知道這個領域發展很快,知識更新日新月異——各種存儲系統和計算架構如雨後春筍層出不窮,相互促進,各顯神通。 至於那個最好,大約只能取決於你實際的需求了。我也是開始學習時間不長,可能很多地方理解不對或者說的不清楚,歡迎大家批評指正。很希望能結交一些研究類似系統的朋友,那麼就算我的目的達到了。呵呵!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章