1. 程式人生 > >hive中與hbase外部表join時記憶體溢位(hive處理mapjoin的優化器機制)

hive中與hbase外部表join時記憶體溢位(hive處理mapjoin的優化器機制)

與hbase外部表(wizad_mdm_main)進行join出現問題:
CREATE TABLE wizad_mdm_dev_lmj_edition_result as
select * 
from  wizad_mdm_dev_lmj_20141120 as w 
JOIN wizad_mdm_main as a ON (a.rowkey = w.guid);

程式啟動後,死迴圈,無反應。最後在進行到0.83時,記憶體溢位失敗。
原因:
預設情況下,Hive會自動將小表加到DistributeCache中,然後在Map掃描大表的時候,去和DistributeCache中的小表做join,這稱為Mapjoin。
這裡wizad_mdm_main是基於HBase的外部表,而這張表在HDFS上的源路徑為 /hivedata/warehouse/wizad.db/wizad_mdm_main,實際這個目錄為空,
因此,Hive優化器認為它是小表,所以,會將這張表資料加到DistributeCache中,造成記憶體溢位。



解決辦法:
SET hive.auto.convert.join=false; 關閉自動轉化MapJoin,預設為true;
SET hive.ignore.mapjoin.hint=false; 關閉忽略mapjoin的hints(不忽略,hints有效),預設為true(忽略hints)。
然後在查詢時候使用hints,/*+ mapjoin(w) */ 將小表w (wizad_mdm_dev_lmj_edition_20141120) 加入到DistributeCache,
Map task在掃描HBase中的大表階段,就可以完成join操作:
SET mapred.job.queue.name=queue3;
SET hbase.client.scanner.caching=5000;
SET hbase.zookeeper.quorum=datanode06,datanode07,datanode08;
SET zookeeper.znode.parent=/hbase;
set hbase.regionserver.lease.period=180000;
SET hive.auto.convert.join=false;
SET hive.ignore.mapjoin.hint=false;
 
INSERT OVERWRITE LOCAL DIRECTORY '/home/wizad/lmj/'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select /*+ mapjoin(w) */ cookie_id,rowkey,fixeddim_map
from wizad_mdm_dev_lmj_edition_20141120 as w JOIN wizad_mdm_main as a

ON (w.guid = a.rowkey);


hive大表與大表join:
1.確保沒有笛卡爾積;
2.確保沒有資料傾斜;
3.增加reduce數;
4.不行再試試分桶join;