【轉】Hive over HBase和Hive over HDFS性能比較分析

轉載:http://lxw1234.com/archives/2015/04/101.htmnode

 

環境配置:緩存

hadoop-2.0.0-cdh4.3.0 (4 nodes, 24G mem/node)oop

hbase-0.94.6-cdh4.3.0 (4 nodes,maxHeapMB=9973/node)性能

hive-0.10.0-cdh4.3.0設計

 

1、查詢性能比較:

query1:
select count(1) from on_hdfs;
select count(1) from on_hbase;
query2(根據key過濾)
select * from on_hdfs
where key = ‘13400000064_1388056783_460095106148962′;
select * from on_hbase
where key = ‘13400000064_1388056783_460095106148962′;
query3(根據value過濾)
select * from on_hdfs where value = ‘XXX';
select * from on_hbase where value = ‘XXX';3d

 

on_hdfs (20萬記錄,150M,TextFile on HDFS)
on_hbase(20萬記錄,160M,HFile on HDFS)orm

 

Hive over HBase

Hive over HBasehtm

 

on_hdfs (2500萬記錄,2.7G,TextFile on HDFS)
on_hbase(2500萬記錄,3G,HFile on HDFS)對象

 

Hive over HBase

Hive over HBaseblog

 

從上圖能夠看出,
對於全表掃描,hive_on_hbase查詢時候若是不設置catching,性能遠遠不及hive_on_hdfs;
根據rowkey過濾,hive_on_hbase性能上略好於hive_on_hdfs,特別是數據量大的時候;
設置了caching以後,儘管比不設caching好不少,但仍是略遜於hive_on_hdfs;

 

2、Hive over HBase原理

 

Hive與HBase利用二者自己對外的API來實現整合,主要是靠HBaseStorageHandler進行通訊,利用 HBaseStorageHandler,Hive能夠獲取到Hive表對應的HBase表名,列簇以及列,InputFormat和 OutputFormat類,建立和刪除HBase表等。
Hive訪問HBase中表數據,實質上是經過MapReduce讀取HBase表數據,其實現是在MR中,使用HiveHBaseTableInputFormat完成對HBase表的切分,獲取RecordReader對象來讀取數據。
對HBase表的切分原則是一個Region切分紅一個Split,即表中有多少個Regions,MR中就有多少個Map;
讀取HBase表數據都是經過構建Scanner,對錶進行全表掃描,若是有過濾條件,則轉化爲Filter。當過濾條件爲rowkey時,則轉化爲對rowkey的過濾;
Scanner經過RPC調用RegionServer的next()來獲取數據;

 

3、性能瓶頸分析

1. Map Task

Hive讀取HBase表,經過MR,最終使用HiveHBaseTableInputFormat來讀取數據,在getSplit()方法中對 HBase表進行切分,切分原則是根據該表對應的HRegion,將每個Region做爲一個InputSplit,即,該表有多少個Region,就 有多少個Map Task;
每一個Region的大小由參數hbase.hregion.max.filesize控制,默認10G,這樣會使得每一個map task處理的數據文件太大,map task性能天然不好;
爲HBase表預分配Region,使得每一個Region的大小在合理的範圍;
下圖是給該表預分配了15個Region,而且控制key均勻分佈在每一個Region上以後,查詢的耗時對比,其本質上是Map數增長。

Hive over HBase

Hive over HBase

 

2. Scan RPC 調用:

  •     在Scan中的每一次next()方法都會爲每一行數據生成一個單獨的RPC請求, query1和query3中,全表有2500萬行記錄,所以要2500萬次RPC請求;

 

  •     掃描器緩存(Scanner Caching):HBase爲掃描器提供了緩存的功能,能夠經過參數hbase.client.scanner.caching來設置;默認是1;緩存 的原理是經過設置一個緩存的行數,當客戶端經過RPC請求RegionServer獲取數據時,RegionServer先將數據緩存到內存,當緩存的數 據行數達到參數設置的數量時,再一塊兒返回給客戶端。這樣,經過設置掃描器緩存,就能夠大幅度減小客戶端RPC調用RegionServer的次數;但並不 是緩存設置的越大越好,若是設置的太大,每一次RPC調用將會佔用更長的時間,由於要獲取更多的數據並傳輸到客戶端,若是返回給客戶端的數據超出了其堆的 大小,程序就會終止並跑出OOM異常;

因此,須要爲少許的RPC請求次數和客戶端以及服務端的內存消耗找到平衡點。

rpc.metrics.next_num_ops
未設置caching,每一個RegionServer上經過next()方法調用RPC的次數峯值達到1000萬:

Hive over HBase

Hive over HBase

 

設置了caching=2000,每一個RegionServer上經過next()方法調用RPC的次數峯值只有4000:

Hive over HBase

Hive over HBase

 

設置了caching以後,幾個RegionServer上的內存消耗明顯增長:

Hive over HBase

Hive over HBase

 

  •     掃描器批量(Scanner Batch):緩存是面向行一級的操做,而批量則是面向列一級的操做。批量能夠控制每一次next()操做要取回多少列。好比,在掃描器中設置setBatch(5),則一次next()返回的Result實例會包括5列。
  •     RPC請求次數的計算公式以下:
    RPC請求次數 =
    (錶行數 * 每行的列數)/ Min(每行的列數,批量大小)  / 掃描器緩存

所以,在使用Hive over HBase,對HBase中的表作統計分析時候,須要特別注意如下幾個方面:

1. 對HBase表進行預分配Region,根據表的數據量估算出一個合理的Region數;

2. rowkey設計上須要注意,儘可能使rowkey均勻分佈在預分配的N個Region上;

3. 經過set hbase.client.scanner.caching設置合理的掃描器緩存;

4. 關閉mapreduce的推測執行:

set mapred.map.tasks.speculative.execution = false;set mapred.reduce.tasks.speculative.execution = false;

相關文章
相關標籤/搜索