Hive調優技巧

1.Fetch抓取

set hive.fetch.task.conversion=more(默認)
1

Fetch 抓取是指,Hive 中對某些狀況的查詢能夠沒必要使用 MapReduce 計算。
該屬性設置爲 more 之後,在全局查找、字段查找、limit 查找等都不走 MapReduce。 設置爲none後全部類型的查找語句都要走MapReduce;node

2.本地模式

set hive.exec.mode.local.auto=true(開啓本地模式)
1

Hive 能夠經過本地模式在單臺機器上 處理全部的任務。對於小數據集,執行時間能夠明顯被縮短
1.開啓本地模式後須要設置local mr的最大輸入數據量,當數據量小於這個值時採用local mr的方式sql

set hive.exec.mode.local.auto.inputbytes.max=134217728(默認)
1

2.開啓本地模式後須要設置local mr的最大輸入文件個數,當數據量小於這個值時採用local mr的方式數據庫

set hive.exec.mode.local.auto.input.files.max=4(默認)
1

3.表的優化

3.1小表join大表 (小表須要在左邊.)

注: 新版的 hive 已經對小表 JOIN 大表和大表 JOIN 小表進行了優化。小表放在左邊和右邊已經沒有明顯區別apache

3.2大表join大表

當一個表內有許多空值時會致使MapReduce過程當中,空成爲一個key值,對應的會有大量的value值, 而一個key的value會一塊兒到達reduce形成內存不足;因此要想辦法過濾這些空值.
1.經過查詢全部不爲空的結果併發

insert overwrite table jointable select n.* from 
   (select * from nullidtable where id is not null ) n left join ori o on n.id = o.id;
12

2.查詢出空值並給其賦上隨機數,避免了key值爲空負載均衡

insert overwrite table jointable
select n.* from nullidtable n full join ori o on 
case when n.id is null then concat('hive', rand()) else n.id end = o.id;
123

注:此方法能夠解決數據傾斜的問題ide

3.3MapJoin

若是不指定 MapJoin 或者不符合 MapJoin 的條件,那麼 Hive 解析器會將 Join 操做轉換成 Common Join,即:在 Reduce 階段完成 join。容易發生數據傾斜。能夠用 MapJoin 把小 表所有加載到內存在 map 端進行 join,避免 reducer 處理。oop

設置MapJoin測試

set hive.auto.convert.join = true(默認)
1

大表小表的閥門值設置(默認25M如下認爲是小表):fetch

set hive.mapjoin.smalltable.filesize=25000000;
1

3.4Group BY

默認狀況下,Map 階段同一 Key 數據分發給一個 reduce,當一個 key 數據過大時就傾斜了並非全部聚合都在reduce端完成,不少聚合操做均可以如今Map端進行部分聚合,最後在Reduce段獲得結果

開啓Map端聚合參數設置
是否在Map段進行聚合,默認爲true

hive.map.aggr = true
1

在Map端進行聚合操做的條目數

hive.groupby.mapaggr.checkinterval = 100000
1

有數據傾斜的時候進行負載均衡(默認是false)

hive.groupby.skewindata = true
1

注: 當選項設定爲 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果會隨機分佈到 Reduce 中,每一個 Reduce 作部分聚合操做,並輸出結果,這樣處理的結果是相同的 Group By Key 有可能被分發到不一樣的 Reduce 中,從而達到負載均衡的目的;第二個 MR Job 再根據預處理的數據結果按照 Group By Key 分佈到 Reduce 中(這個過程能夠 保證相同的 Group By Key 被分佈到同一個 Reduce 中),最後完成最終的聚合操做。

3.5Count(Distinct)去重統計

Count Distinct是使用了一個mapreduce ,當數據較少時無影響當數據較大時 只使用一個MapReduce將很難完成job。這是須要用到分組 Group BY 會使用2個MapReduce完成由於設置了 set mapreduce.job.reduces = 5; 因此第一個MapReduce的過程是經過一個map和5個reduce來完成這樣減輕了reduce的負載, 雖然會多用一個 Job 來完成,但在數據量大的狀況下,這個絕對是值得的。

3.6行列過濾

  • 列處理: 在select中,只拿須要的列,儘可能使用分區過濾,少用select*
  • 行處理: 在分區剪裁中,當使用外關聯時,若是將副表的過濾條件寫在where後面那麼就會先全表關聯,以後再過濾。

實例:
1.測試先關聯兩張表,再用 where 條件過濾

hive (default)> select o.id from bigtable bjoin ori o on o.id = b.idwhere o.id <= 10;
1

2.經過子查詢後,再關聯表

hive (default)> select b.id from bigtable b join (select id from ori where id <= 10 ) o on b.id = o.id;
1

3.7.動態分區

關係型數據庫中,對分區表 Insert 數據時候,數據庫自動會根據分區字段的值,將數據插入到相應的分區中,Hive 中也提供了相似的機制,即動態分區(Dynamic Partition),只不過,使用 Hive 的動態分區,須要進行相應的配置。
首先要設置的屬性

set hive.exec.dynamic.partition = true;
set hive.exec.dynamic.partition.mode = nonstrict;
set hive.exec.max.dynamic.partitions = 1000;
set hive.exec.max.dynamic.partitions.pernode = 100;
set hive.exec.max.created.files = 100000;
set hive.error.on.empty.partition = false;
123456

模擬動態分區

insert overwrite table ori_partitioned_target partition (p_time)
select id, time, uid, keyword, url_rank, click_num, click_url, p_time from ori_partitioned;
12

4.數據傾斜

4.1合理設置Map數

設置切片值

set mapreduce.input.fileinputformat.split.maxsize=???
1

4.2小文件進行合併

在 map 執行前合併小文件,減小 map 數:CombineHiveInputFormat 具備對小文件進行
合併的功能(系統默認的格式)。HiveInputFormat 沒有對小文件合併功能。

set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
1

4.3複雜文件增長Map數

set mapreduce.job.maps =???
1

4.4合理設置Reduce數

1.調整reduce的個數方法一
每一個Reduce處理的數據默認是256MB

hive.exec.reducers.bytes.per.reducer=256000000
1

每一個任務最大的reduce數,默認爲1009

hive.exec.reducers.max=1009
1

計算reduce數的公式

N=min(參數2,總輸入數據量/參數1)
1

2.調整reduce個數的方法二

set mapreduce.job.reduces=???
1

3.reduce個數不是越多越好

  • 過多的啓動和初始化 reduce 也會消耗時間和資源;
  • 另外,有多少個 reduce,就會有多少個輸出文件,若是生成了不少個小文件,那麼若是這些小文件做爲下一個任務的輸入,則也會出現小文件過多的問題;在設置 reduce 個數的時候也須要考慮這兩個原則:處理大數據量利用合適的 reduce 數;使單個 reduce 任務處理數據量大小要合適;

4.5並行執行

經過設置參數 hive.exec.parallel 值爲 true,就能夠開啓併發執行。不過,在共享集羣中,須要注意下,若是 job 中並行階段增多,那麼集羣利用率就會增長。

set hive.exec.parallel=true; //打開任務並行執行
set hive.exec.parallel.thread.number=16; //同一個 sql 容許最大並行度,默認爲 8。
相關文章
相關標籤/搜索