1. 程式人生 > >Hive和並行數據倉庫的比較

Hive和並行數據倉庫的比較

part 模式 secondary 依次 代碼 文件格式 信息 eset fault

最近分析和比較了Hive和並行數據倉庫的架構,本文記下一些體會。
Hive是架構在Hadoop MapReduce Framework之上的開源數據分析系統。 Hive具有如下特點:

1. 數據以HDFS文件的形式存儲,從而可以很方便的使用外部文件
2. 元數據存儲獨立於數據存儲之外,從而解耦合元數據和數據,同樣的數據,不同的用戶可以有不同的元數據
3. 查詢計劃被分解為多個MapReduce Job,並按照依賴關系依次執行,復用了MapReduce的執行架構
4. 靈活的存儲格式,通過ObjectInspector將對數據列的訪問與數據的具體存儲格式解耦合,同一行數據在同一個數據處理流中可以以不同的格式出現
5. 基於規則的查詢優化器,依次使用規則轉換邏輯計劃

下面,我們就把Hive跟傳統的並行數據倉庫進行一下深入的比較:

1. 存儲引擎。 並行數據倉庫需要先把數據裝載到數據庫中,按特定的格式存儲成特定的頁文件,然後才能查詢;而Hive則不用裝載數據,也不用格式轉換,Hive內置了多種文件格式的支持,並且可以使用用戶定制的格式實現(inputformat),這樣大大節省了數據導入的開銷。傳統數據倉庫是把數據導入系統中,而Hive則是動態的將對數據處理的邏輯(代碼)導入系統中。

2. 執行引擎。Hive架構於MapReduce Framework之上,執行計劃的靈活性較差,優化器可做的選擇很少,例如:Join算法只有Grace Hash Join一種選擇,性能更加優秀且穩定的Hybrid Hash Join則無法實現; Map端的Group-by算法只有Hash Group-by一種選擇, Reduce端的Group-by只有sort group-by一種選擇(不然MapReduce提供的sort就浪費了); limit無法和sort融合起來,很多情況下,用堆排序來融合limit與sort會更加高效。 Join, Group-by, Limit在OLAP,日誌分析等任務中非常常用的Operator,而Hive在這3個Operator的實現上都依賴於MapReduce Frameowork提供的partition和sort,好處是實現比較簡單,缺點是效率往往不是最優的。 然而,由於MapReduce數據處理流程的限制,效率更高的算法卻無法實現。 相反,並行數據倉庫實現了各種算法,它的查詢優化器可以更加靈活的選擇這3個Operator的不同實現。

3. 查詢優化器。大多數商用數據倉庫使用基於代價的優化器,在生成查詢計劃時,利用元數據中的統計信息估算每個operator要處理的數據量,選取代價較低的執行計劃。不過,這些商用數據倉庫的都起步於基於規則的查詢優化器,而Hive正處於這樣一個類似的起步階段。因而Hive查詢優化器能做的優化並不多,僅限於10幾條轉換規則。

4. 索引和緩沖管理。 對於查詢來說,索引的作用至關重要,盡管Hive中的partition起到和索引類似的作用,但還比較初級,與並行數據倉庫較為完善的索引(primary,secondary, clustered, unclustered)還有很大差距。 當然,Hive也沒有緩沖區管理機制,只能依賴於文件系統的緩沖機制;並行數據倉庫往往禁用操作系統的緩沖機制,針對不同的查詢的特點設計了多種緩沖機制,從而優化了性能。

5. 並行擴展性。MapReduce將MR job的中間結果保存到Map Task的本地硬盤,從而MR Job的容錯性非常好,Hive自然的利用了這一點;Hive執行計劃中,每一個MapReduce job又把處理結果寫到HDFS,從而又利用了HDFS的容錯性。 這樣,在一個Hive查詢的執行中,如果某個節點出現故障了,只需要重新調度執行該節點的任務即可,不需要重新提交查詢。 因此,Hive有非常好的intra-query fault-tolerance,所以可擴展性非常強,例如一個查詢可以在4000個節點上同時跑;缺點是大大減少了pipeline parallelism的機會。 並行數據倉庫往往采用的是pipeline架構,上遊的Operator每產生一條數據就會送去下遊的Operator。這樣的好處是最大化了pipeline parallelism並避免了中間結果的磁盤讀寫,但是,當一個查詢運行於並行數據庫上時,一旦一個節點出現故障,並行數據倉庫就必須重新執行該查詢。所以,當一個集群中的單點故障發生率較高時,並行數據倉庫的性能就會下降了。假設每個節點故障發生率是0.01%,那麽1000個節點的集群中,單點故障發生率則為10%;假設每個節點故障發生率是0.0001%,那麽5000個節點的集群中,單點故障發生率為0.5%!

6. 內存拷貝開銷。 千萬別小看這一點,內存拷貝會很大程度上拖累系統性能。 我們可以註意到,Hive中所有的哈希,比較,數值運算操作,都需要操作在Writable Object上,而每次重置(reset)這些Writable Object,都需要將數據從byte array拷貝到這些對象的byte[]成員中。 在更精巧的實現中,很多內存拷貝其實是可以避免的,並行數據倉庫往往做了很多優化(甚至包含操作系統內核的優化,比如Teradata的PDE)去節省不必要的內存拷貝,從而又帶來了性能提升。

在實際應用中,到底該選用Hive還是並行數據倉庫,取決於這些:
1. 錢,Hive是開源的,並行數據倉庫(db2, teradata, netezza, vertica)是非常昂貴的
2. 還是錢,Hive只需要普通機器集群,並且集群節點的操作系統和硬件都可以是異構的,單點故障發生率高也無所謂;並行數據倉庫往往希望使用性能較高的服務器作為集群節點,從而單點故障發生率可以控制在一個非常低的範圍。
3. 數據規模,如果是Google, Facebook, Baidu這種規模的應用,需要幾千甚至上萬節點的集群,目前的商業並行數據倉庫產品就很難支撐了;如果是沃爾瑪,eBay這些應用,並行數據倉庫還是完全可以勝任的,並且性能會遠優於Hive。

此文旨在拋磚引玉,歡迎大家進行更多的比較:-)

=============================================================

另補充我的一些觀點:

Hive本意是在Hadoop的MapReduce編程模型上進行包裝,使其支持聲明式的SQL查詢,其各種opr都是使用MapReduce模型模擬實現。這樣的好處就是與Hadoop無縫融合,但是,MapReduce模型最適用的場景是聚集類的操作,即數據庫中的Group By,其模型並不是為Join量身打造,即使能夠通過設計實現Join操作,但是效率以及可選擇性上也大大折扣,有點削足適履的感覺。

我覺得如果不拘束在MapReduce模型上,而是對於各種操作尋求最合適的模型而不是拘束在MapReduce模型上,但是充分吸收其Fault Tolerance的特性,可能會較好。

但是,Fault Tolerance的滿足需要對中間結果進行物化,這與Pipeline又會矛盾。兩者需要尋找一個平衡點。我覺得部分物化、部分Pipeline的方式也許是一種選擇,類似於checkpoint。這樣Fault Tolerance的粒度不是MapReduce模式下的單個操作,也不是Pipeline模式下的整個查詢,而是居中,即查詢中的子操作塊。

總的感覺,Hive的工作更傾向於工程,而不是模式的創新。但是作為初級產品,還是很有意義的。

Hive和並行數據倉庫的比較