一.前述
本節主要描述Hive的優化使用,Hive的優化著重強調一個 把Hive SQL 當做Mapreduce程式去優化
二.主要優化點
1.Hive執行方式:
本地模式
叢集模式
本地模式
開啟本地模式:
set hive.exec.mode.local.auto=true;
注意:
hive.exec.mode.local.auto.inputbytes.max預設值為128M
表示載入檔案的最大值,若大於該配置仍會以叢集方式來執行! 對於小表可以直接從從hdfs直接拿到本地計算
2.平行計算
通過設定以下引數開啟並行模式:
set hive.exec.parallel=true;
注意:hive.exec.parallel.thread.number
(一次SQL計算中允許並行執行的job個數的最大值)
3.嚴格模式
通過設定以下引數開啟嚴格模式:
set hive.mapred.mode=strict;
(預設為:nonstrict非嚴格模式)
查詢限制:
對於分割槽表,必須新增where對於分割槽欄位的條件過濾;
order by語句必須包含limit輸出限制;
限制執行笛卡爾積的查詢。
4.Hive排序(重要)
Order By - 對於查詢結果做全排序,只允許有一個reduce處理
(當資料量較大時,應慎用。嚴格模式下,必須結合limit來使用)
Sort By - 對於單個reduce的資料進行排序(這樣最後的資料有可能排序結果不準!!!!)
Distribute By - 分割槽排序,經常和Sort By結合使用(SortBy對於最後的分割槽排序)
Cluster By - 相當於 Sort By + Distribute By
(Cluster By不能通過asc、desc的方式指定排序規則;
可通過 distribute by column sort by column asc|desc 的方式) !!!
5 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
自動的mapjoin
通過修改以下配置啟用自動的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時,其表的最大值)
6.Map-Side聚合(一般在聚合函式sum,count時使用)
通過設定以下引數開啟在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(自動優化解決思路如下):
Map端兩個MapReduce,第一個Mapreduce隨機來分發資料。
然後另一個Mapreduce根據此Mapreduce的結果在到Reduce的機器上去拉取資料。
7.控制Hive中Map以及Reduce的數量
Map數量相關的引數
mapred.max.split.size
一個split的最大值,即每個map處理檔案的最大值
mapred.min.split.size.per.node
一個節點上split的最小值
mapred.min.split.size.per.rack
一個機架上split的最小值
Reduce數量相關的引數
mapred.reduce.tasks
強制指定reduce任務的數量
hive.exec.reducers.bytes.per.reducer
每個reduce任務處理的資料量
hive.exec.reducers.max
每個任務最大的reduce數
PS:一般工作中肯定不會改!!!桶的個數是Reduce的個數。
8. Hive - JVM重用(類似於執行緒池)
適用場景:
1、小檔案個數過多
2、task個數過多
通過 set mapred.job.reuse.jvm.num.tasks=n; 來設定
(n為task插槽個數)
缺點:設定開啟之後,task插槽會一直佔用資源,不論是否有task執行,直到所有的task即整個job全部執行完成時,才會釋放所有的task插槽資源!