MapReduce:一個重大的倒退

翻譯:MapReduce:一個重大的倒退
  這篇文章是由databasecolumn的幾個數據庫大牛寫的,簡要的介紹了MapReduce以及將其與現代數據庫管理系統進行了對比,並指出了一些不足之處。本文純屬學習性翻譯,從多方面來了解MapReduce,不代表完全贊同原文的觀點。請讀者也辯證的看。

         一月八號,一個數據庫專欄的讀者詢問我們關於對新的分佈式數據庫研究成果的意見。我們在這結合MapReduce談談我們的看法。現在是討論這個問題的不錯的時機,因爲最近媒體上到處充斥着新的革命所謂“雲計算”的信息。這種模式需要利用大量的(低端)處理器並行工作來解決計算問題。實際上,這建議利用大量的低端處理器來構建數據中心,而不是利用數目少的多的高端服務器來構建。

        舉例來說,IBM和Google已經宣佈計劃用1000臺處理器構建的集羣提供給部分大學,傳授學生們如何使用MapReduce工具在這些集羣上編程。加利福尼亞大學伯克利分校甚至打算開設使用MapReduce框架編程的課程。我們對MapReduce支持者大肆炒作它如何如何能夠開發更加具有擴展性,以及數據密集型程序感到震驚。MapReduce可能在某些特定類型的通用計算上是個不錯的想法,但是對於數據庫社區來說:

1.    從大規模數據應用程序模型來說是一個巨大的倒退。
2.    不是一個最優實現,因爲它使用蠻力來代替索引。
3.    一點都不新奇,它只是實現了一個特定的25年前就有的衆所周知的技術。
4.    失去了大部分目前數據庫管理系統的特性。
5.    不能兼容所有目前數據庫管理系統用戶已經依賴的工具。

      首先我們將簡要的討論下MapReduce到底是什麼,然後我們將就上面5點進行更深層次的討論。


MapReduce是什麼?

        MapReduce基礎出發點是很易懂的。它由稱爲map和reduce的兩部分用戶程序組成,然後利用框架在計算機集羣上面根據需求運行多個程序實例來處理各個子任務,然後再對結果進行歸併。

        Map程序從輸入流中讀取一組“記錄”,然後對記錄進行需要的過濾或者轉換,然後輸出一組記錄(key,data)。當map程序生成輸出記錄時,一個分割方法將記錄劃分爲M個不相交的塊並賦予一個鍵值。這個分割方法一般是一個hash函數,只要這個決定性的函數能夠滿足就行。當一個塊被填充後,它將寫入磁盤,map程序結束的時候每個塊都將輸出M個文件。

        通常情況下,將有多個map的程序實例運行在計算機集羣的不同的節點上。每個map實例都將由MapReduce調度程序分配一個不重複的輸入文件來獨立執行。如果有N個節點參與map程序執行,那麼N個節點中的每個節點都將有M個文件存儲在各自的磁盤上,也就是說,總共將有N*M個文件。Fi,j, 1 ≤ i ≤ N, 1 ≤ j ≤ M.

        其中有個值得注意的關鍵點是每個map實例都必須使用一個相同的hash方法。這樣,所有的擁有相同hash值的輸出記錄纔會寫入相應的輸出文件。

        MapReduce的第二個階段就是執行M個reduce的程序實例。Rj, 1 ≤ j ≤ M.每個reduce實例Rj的輸入文件由文件 Fi,j組成,1 ≤ i ≤ N。還有一個值得注意的是:所有從map階段輸出的擁有相同hash值的記錄,無論是哪個map實例生成的,都將由一個相同的reduce實例處理。在map-reduce框架收集整理之後,所有的輸入記錄都將根據它們的鍵值(key)編組然後提供給reduce程序。跟map程序一樣,reduce程序也可以做任意的計算。所以,你可以對輸入的記錄做任何你想要的事情。舉例來說,可能會對記錄的別的字段進行一些附加的計算。每個reduce實例都可以將記錄寫入輸出文件,只要是MapReduce計算所需要的結果。

        用SQL來做類比,map象聚合(aggregate)查詢中的group-by子句。Reduce則類似計算group-by起來的行的聚合函數(例如求平均等)。

        現在我們基於這個計算模型來討論上面提到的五點:

1.    MapReduce是一個數據庫存取的退步

        做爲一個數據處理模型,MapReduce呈現出了一個巨大的退步。數據庫社區從IBM在1968年第一次發佈IMS以來的四十年中學到了以下三個經驗:

* 結構描述是好的。
* 將結構描述從程序中分離是好的
* 高階的訪問語言是好的


         MapReduce沒有吸引上面三個經驗中的任何一個,而且還退步到了現在數據庫管理系統發明前的60年代。

         數據庫管理系統社區學習到的關於最重要的結構描述就是:記錄的字段和它的數據類型都記錄在存儲系統中。更重要的是,數據庫管理系統的運行時可以保證所有的記錄都遵守結構描述。這是避免將垃圾數據添加到數據集中的最好的方法。MapReduce沒有這樣的方法,也沒有避免將垃圾數據添加到數據集中的控制。一個毀壞的數據集可以悄無聲息的破壞整個使用這個數據集的MapReduce程序。

        將數據描述與程序分離也很關鍵。如果開發者想在一個數據集上開發一個新的程序,他必須先去了解記錄結構。在現代數據庫管理系統中,結構描述存儲在系統目錄中,而且可以被用戶用SQL查詢來了解它的結構。與此相反的是,如果數據描述不存在,或者隱藏在程序之中,開發者要了解這個數據結構必須通過檢查原有的代碼。這個工作不僅僅是非常沉悶的,而且開發者必須先找到這個程序的源代碼。如果沒有相應的結構描述存在,後面的這個沉悶的問題將在所有的MapReduce程序中存在。

        在1970年數據庫管理系統社區,關係型數據庫支持者和數據系統語言協會(Codasyl)支持者進行了一場“劇烈的辯論”。其中一個最大的爭議是數據庫管理系統的訪問程序以何種方式訪問:

* 用統計來獲取你想要的數據(關係型的觀點)
* 提供一個算法來進行數據訪問(Codasyl的觀點)


         爭論的結果已經是古代史了,但是整個世界都看到了高階語言的價值以及關係型系統的勝利。以高階語言的形式編程更加容易編寫,易於修改,而且方便一個新來者的理解。
Codasyl被批判爲“以彙編語言的形式來對數據庫管理系統進行訪問”。MapReduce程序員有點類似Codasyl程序員。他們用低階的語言來處理低階記錄。沒有人提倡迴歸彙編語言,類似的,不應該強制任何人用MapReduce來編程。

        MapReduce提倡者可能會反對說他們的數據集沒有數據描述的假設。那麼我們解除這個斷言。在從輸入數據記錄中提取一個key時,map方法在每個輸入記錄中至少依賴一個存在的數據字段。相同Reduce方法的持有者從接受到的處理數據中計算一些值。

        基於Google的BigTable或者Hadoop的Hbase來編寫MapReduce程序並不會真正重大的改變這種狀況。在相同的表中使用一種自描述元組格式(行號,列名,值)確實可以擁有不同的架構。但是,BigTable和Hbase並沒有提供邏輯上的獨立。以視圖機制舉例來說,視圖有一個明顯的簡化作用,當邏輯數據描述(logic schema)改變後,仍保持程序運行。

2.    MapReduce是一個粗燥的實現

       所有現在數據庫管理系統使用hash或者B-tree來索引加快對數據的訪問。如果一個用戶在查找一個記錄集的子記錄集(比如僱員中誰的薪水在10000或者誰在鞋生產部門),那麼他可以使用索引來有效的縮減查找範圍。另外,還提供了一個查詢優化器來決定到底是使用索引還是進行一個殘忍野蠻的順序查詢。

        MapReduce沒有索引,理所當然的只能使用蠻力來作爲處理選項。而不管索引在當前情況下是否是一個最好的訪問機制。

        一個值得爭論的是,MapReduce提出的自動的在計算機集羣中提供並行計算的價值。其實這個特性在1980年時代就被數據庫管理系統研究社區研究過了,多個原型被提出來,比如Gamma,Bubba和Grace。商業化的利用這些思想在系統則在80年代末期,比如Teradata。

        概括起來說,在前20年已經出現了高性能,商業化的,面向網格計算機羣的SQL引擎(帶結構描述和索引)。MapReduce跟這些系統相比並沒有那麼好。

         MapReduce同時存在很多底層的實現問題,特別是數據交換和數據斜交的情況。

         一個因素是MapReduce支持者好像沒有注意到關於數據斜交的問題。就像在“平行數據庫系統:未來的高性能數據庫系統”中提到的,數據斜交是構建成功高擴展性並行查詢系統的巨大障礙。這個問題重現在map階段,當擁有相同鍵的數據擁有大幅度差異的時候。這個差異,反過來導致某些reduce實例花費比其它實例更長甚至常很多的時間來運行。結果就是計算的運行時間由速度最慢的那個reduce實例決定。平行數據庫社區已經廣泛的研究了這個問題並且擁有了成熟的,MapReduce社區可能願意採納的解決方案。

        還有第二個嚴重的性能問題被MapReduce支持者掩蓋了。回憶N個map實例中的每個實例都將生成M個輸出文件。每個都分發給不同的reduce實例。這些文件都被寫入本地硬盤以備map實例使用。如果N是1000,M是500,那麼在map階段將生成500000個本地文件。當reduce階段開始,500個reduce實例必須讀取1000個輸入文件,必須使用類似FTP的協議將每個輸入文件從各個map實例運行的節點中獲取(pull)過來。在100秒內所有reduce實例將同時的運行起來,不可避免的會發生兩個或者更多個reduce實例企圖並行的從同一個map節點中獲取輸入文件,包括大量的磁盤搜索,當超過因子20時,將極大的降低磁盤的有效傳輸率。這就是爲什麼並行數據庫系統不實現分割文件,而使用推(push to sockets)來代替拉(pull)。因爲MapReduce通過實現分割文件來獲得優秀的容錯性,不好說如果MapReduce框架修改成使用推(push)模型是否會成功。

        鑑於實驗評估,我們嚴重的懷疑MapReduce在大規模應用中會表現的很好。MapReduce的實現者還需要好好的研究過去25年來並行數據庫管理系統的研究文獻。

3.    MapReduce並不新奇

        MapReduce社區看起來感覺他們發現了一個全新的處理大數據集的模型。實際上,MapReduce所使用的技術至少是20年前的。將大數據集劃分爲小數據集的思想是在Kitsuregawa首次提出的“Application of Hash to Data Base Machine and Its Architecture”的基礎上發展出來的一個新的連接算法。在“Multiprocessor Hash-Based Join Algorithms”中,Gerber演示瞭如何將Kitsuregawa的技術擴展到使用聯合分區表,分區執行以及基於hash的分割來連接並行的無共享集羣。DeWitt演示瞭如何採用這些技術來執行有group by子句以及沒有group by子句的並行聚合。DeWitt和Gray描述了並行數據庫系統以及他們如何處理查詢。Shatdal和Naughton探索了並行聚合的替代策略。

       Teradata已經出售利用這些技術構建的數據庫管理系統20多年了,而這些技術正是MapReduce一夥聲稱的發明的技術。

        當然MapReduce提倡者將毫無疑問的聲稱他們編寫的MapReduce函數實現他們的軟件與使用並行SQL實現有多麼大的不同,我們必須提醒他們,POSTGRES已經在80年代中期就支持了用戶自定義函數以及用戶自定義聚合。本質上來說,從1995年Illustra引擎開始算,所有現代數據庫系統都提供了類似的功能很長一段時間了。

4.    MapReduce失去了很多特性

       所有下面的特性都被現在的數據庫管理系統提供了,而MapReduce沒有:

* 批量導入     —— 將輸入數據轉化成想要的格式並加載到數據庫中
* 索引               —— 如上文所述
* 更新               —— 改變數據集中的數據
* 事務               —— 支持並行更新以及從失敗的更新中恢復
* 完善的約束        —— 防止垃圾數據添加到數據集
* 完善的引用        —— 類似FK,防止垃圾數據的存在
* 視圖               —— 底層邏輯數據描述可以改變但不需要重寫程序

       簡單的說來,MapReduce只提供了現在數據庫管理系統的函數性功能。

5.    MapReduce與現有的數據庫管理系統工具不兼容

      一個現代的SQL數據庫管理系統都擁有如下可用的工具:

* 報表                —— (比如水晶報表) 將數據友好的展示給人
* 商業智能工具        —— (比如Business Objects or Cognos)允許在數據倉庫中進行特定查詢
* 數據挖掘工具        —— (比如Oracle Data Mining)允許用戶在大數據集中發現數據規律
* 複製工具            —— 允許用戶在不同的數據庫中進行復制傳輸
* 數據庫設計工具    —— 幫助用戶構建數據庫

        MapReduce不能使用這些工具,同時它也沒有自己的工具。直到它能與SQL兼容或者有人編寫了這些工具,MapReduce仍然在端到端的任務中顯得十分困難。



總結

        看到一個龐大的社區參與到設計和實現可擴展的查詢處理技術中是值得振奮的。但是,我們認爲他們不應該忽視超過40年的數據庫技術的經驗。——特別是擁有巨大優勢的數據描述模型以及物理數據與邏輯數據互相獨立;描述性的查詢語言(比如SQL);提供設計,實現,以及維護程序。此外,計算機科學社區不應該孤立起來而應該多讀讀別的社區的技術文獻。我們鼓勵好好的研究下近25年來的並行數據庫管理系統的技術文獻。最後,在MapReduce達到現代數據庫管理系統之前,還有很多的沒實現的特性以及必須的工具需要添加。

        我們完全的理解利用數據庫來解決他們的問題是可以的。數據庫社區意識到數據庫系統解決他們的問題使用起來操作過於“複雜”。數據庫社區也從MapReduce提供的優秀的容錯機制中學到了不少的有價值的東西。最後我們注意到一些數據庫的研究者開始探索以MapReduce框架爲基礎來構建可擴展的數據庫系統,yahoo!研究中心的Pig項目就是其中一個努力的結果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章