Hadoop學習(9)——Hive優化

(1)核心思想:Hive SQL 當做Mapreduce程序去優化

(2)以下SQL不會轉爲Mapreduce來執行

  • select僅查詢本表字段
  • where僅對本表字段做條件過濾

(3)Explain 顯示執行計劃:EXPLAIN [EXTENDED] query

(4)Hive抓取策略:Hive中對某些情況的查詢不需要使用MapReduce計算

(5)抓取策略 :Set hive.fetch.task.conversion=none/more;

(6)Hive運行方式:本地模式、集羣模式

本地模式:

開啓本地模式:set hive.exec.mode.local.auto=true;

注意:

  • hive.exec.mode.local.auto.inputbytes.max默認值爲128M
  • 表示加載文件的最大值,若大於該配置仍會以集羣方式來運行!

(7)並行計算

通過設置以下參數開啓並行模式:set hive.exec.parallel=true;

注意hive.exec.parallel.thread.number(一次SQL計算中允許並行執行的job個數的最大值)

(8)嚴格模式

通過設置以下參數開啓嚴格模式:set hive.mapred.mode=strict;(默認爲:nonstrict非嚴格模式)

查詢限制:

1、對於分區表,必須添加where對於分區字段的條件過濾;

2order by語句必須包含limit輸出限制;

3、限制執行笛卡爾積的查詢。

(9)Hive排序優化

Order By - 對於查詢結果做全排序,只允許有一個reduce處理
(當數據量較大時,應慎用。嚴格模式下,必須結合limit來使用)
Sort By - 對於單個reduce的數據進行排序
Distribute By - 分區排序,經常和Sort By結合使用
Cluster By - 相當於 Sort By + Distribute By
(Cluster By不能通過asc、desc的方式指定排序規則;
可通過 distribute by column sort by column asc|desc 的方式)

(10)Hive Join優化

Join計算時,將小表(驅動表)放在join的左邊

Map Join:在Map端完成Join:

兩種實現方式:

1、SQL方式,在SQL語句中添加MapJoin標記(mapjoin hint)
語法:
SELECT  /*+ MAPJOIN(smallTable) */  smallTable.key,  bigTable.value 
FROM  smallTable  JOIN  bigTable  ON  smallTable.key  =  bigTable.key;
2、開啓自動的MapJoin

自動的map join:

通過修改以下配置啓用自動的mapjoin:set hive.auto.convert.join = true;(該參數爲true時,Hive自動對左邊的表統計量,如果是小表就加入內存,即對小表使用Map join

相關配置參數:

hive.mapjoin.smalltable.filesize;  
(大表小表判斷的閾值,如果表的大小小於該值則會被加載到內存中運行)
hive.ignore.mapjoin.hint;
(默認值:true;是否忽略mapjoin hint 即mapjoin標記)
hive.auto.convert.join.noconditionaltask;
(默認值:true;將普通的join轉化爲普通的mapjoin時,是否將多個mapjoin轉化爲一個mapjoin)
hive.auto.convert.join.noconditionaltask.size;
(將多個mapjoin轉化爲一個mapjoin時,其表的最大值)

儘可能使用相同的連接鍵(會轉化爲一個MapReduce作業)

大表join大表:

key過濾有時join超時是因爲某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾。

key轉換有時雖然某個key爲空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表akey爲空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer

(11)Map-Side聚合

通過設置以下參數開啓在Map端的聚合:set hive.map.aggr=true;

相關配置參數:

hive.groupby.mapaggr.checkinterval: 
map端group by執行聚合時處理的多少行數據(默認:100000)
hive.map.aggr.hash.min.reduction: 
進行聚合的最小比例(預先對100000條數據做聚合,若聚合之後的數據量/100000的值大於該配置0.5,則不會聚合)
hive.map.aggr.hash.percentmemory: 
map端聚合使用的內存的最大值
hive.map.aggr.hash.force.flush.memory.threshold: 
map端做聚合操作是hash表的最大可用內容,大於該值則會觸發flush
hive.groupby.skewindata
是否對GroupBy產生的數據傾斜做優化,默認爲false

(12)合併小文件

文件數目小,容易在文件存儲端造成壓力,給hdfs造成壓力,影響效率

設置合併屬性:

是否合併map輸出文件:hive.merge.mapfiles=true
是否合併reduce輸出文件:hive.merge.mapredfiles=true;
合併文件的大小:hive.merge.size.per.task=256*1000*1000

去重統計:

數據量小的時候無所謂,數據量大的情況下,由於COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BYCOUNT的方式替換

(13)Hive - JVM重用

適用場景:

1、小文件個數過多

2task個數過多

通過 set mapred.job.reuse.jvm.num.tasks=n; 來設置(ntask插槽個數)

缺點:設置開啓之後,task插槽會一直佔用資源,不論是否有task運行,直到所有的task即整個job全部執行完成時,纔會釋放所有的task插槽資源!

 

 

 

 

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