Hive 企業級調優點整理
目錄:
1、Fetch 抓取
Fetch 抓取是指,Hive 中對某些情況的查詢可以不必使用 MapReduce 計算。
例如:
SELECT * FROM employees;在這種情況下,Hive 可以簡單地讀取 employee 對應的存儲目錄下的文件,然後輸出查詢結果到控制檯。
在 hive-default.xml.template 文件中 hive.fetch.task.conversion 默認是 more,老版本 hive
默認是 minimal,該屬性修改爲 more 以後,在全局查找、字段查找、limit 查找等都不走mapreduce。
(1)把 hive.fetch.task.conversion 設置成 none,然後執行查詢語句,都會執行 mapreduce程序。
set hive.fetch.task.conversion=none;
(2)把 hive.fetch.task.conversion 設置成 more,然後執行查詢語句,如下查詢方式都不會執行 mapreduce 程序。
set hive.fetch.task.conversion=more;
2、本地模式
Hive 可以通過本地模式在單臺機器上處理所有的任務。對於小數據集,執行時間可以明顯被縮短。
用戶可以通過設置 hive.exec.mode.local.auto 的值爲 true,來讓 Hive 在適當的時候自動啓動這個優化。
1)開啓本地模式,並執行查詢語句
set hive.exec.mode.local.auto=true; //開啓本地 mr
2)關閉本地模式,並執行查詢語句
hive (default)> set hive.exec.mode.local.auto=false;
3、表的優化
將 key 相對分散,並且數據量小的表放在 join 的左邊,這樣可以有效減少內存溢出錯誤發生的機率;再進一步,可以使用 Group 讓小的維度表(1000 條以下的記錄條數)先進內存。在 map 端完成 reduce。
(1)關閉 mapjoin 功能(默認是打開的)
set hive.auto.convert.join = false;
(2)設置 5 個 reduce 個數
set mapreduce.job.reduces = 5;
4、MapJoin
如果不指定 MapJoin 或者不符合 MapJoin 的條件,那麼 Hive 解析器會將 Join 操作轉換成 Common Join,即:在 Reduce 階段完成 join。容易發生數據傾斜。可以用 MapJoin 把小表全部加載到內存在 map 端進行 join,避免 reducer 處理。
1)開啓 MapJoin 參數設置:
(1)設置自動選擇 Mapjoin
set hive.auto.convert.join = true; 默認爲 true
(2)大表小表的閾值設置(默認 25M 一下認爲是小表):
set hive.mapjoin.smalltable.filesize=25000000;
2)MapJoin 工作機制
(1)開啓 Mapjoin 功能
set hive.auto.convert.join = true; 默認爲 true
5、 Group By
默認情況下,Map 階段同一 Key 數據分發給一個 reduce,當一個 key 數據過大時就傾斜了。
並不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端進行部分聚合,最後在 Reduce 端得出最終結果。
1)開啓 Map 端聚合參數設置
(1)是否在 Map 端進行聚合,默認爲 True
hive.map.aggr = true
(2)在 Map 端進行聚合操作的條目數目
hive.groupby.mapaggr.checkinterval = 100000
(3)有數據傾斜的時候進行負載均衡(默認是 false)
hive.groupby.skewindata = true
數據傾斜文章:
https://blog.csdn.net/weixin_46163590/article/details/106098548
6、 Count(Distinct) 去重統計
數據量小的時候無所謂,數據量大的情況下,由於 COUNT DISTINCT 操作需要用一個Reduce Task 來完成,這一個 Reduce 需要處理的數據量太大,就會導致整個 Job 很難完成,一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替換:
採用 GROUP by 去重 id
hive (default)> select count(id) from (select id from bigtable group by id) a;
7、笛卡爾積
儘量避免笛卡爾積,join 的時候不加 on 條件,或者無效的 on 條件,Hive 只能使用 1 個
reducer 來完成笛卡爾積。
8、 行列過濾
列處理:在 SELECT 中,只拿需要的列,如果有,儘量使用分區過濾,少用 SELECT *。
行處理:在分區剪裁中,當使用外關聯時,如果將副表的過濾條件寫在 Where 後面,那麼就會先全表關聯,之後再過濾,比如:
案例實操:
(1)測試先關聯兩張表,再用 where 條件過濾
hive (default)> select o.id from bigtable b
join ori o on o.id = b.id where o.id <= 10;
(2)通過子查詢後,再關聯表
hive (default)> select b.id from bigtable b
join (select id from ori where id <= 10 ) o on b.id = o.id;
9.動態分區調整
關係型數據庫中,對分區表 Insert 數據時候,數據庫自動會根據分區字段的值,將數據插入到相應的分區中,Hive 中也提供了類似的機制,即動態分區(Dynamic Partition),只不過,使用 Hive 的動態分區,需要進行相應的配置。
1)開啓動態分區參數設置
(1)開啓動態分區功能(默認 true,開啓)
hive.exec.dynamic.partition=true
(2)設置爲非嚴格模式(動態分區的模式,默認 strict,表示必須指定至少一個分區爲靜態分區,nonstrict 模式表示允許所有的分區字段都可以使用動態分區。)
hive.exec.dynamic.partition.mode=nonstrict
(3)在所有執行 MR 的節點上,最大一共可以創建多少個動態分區。
hive.exec.max.dynamic.partitions=1000
(4)在每個執行 MR 的節點上,最大可以創建多少個動態分區。該參數需要根據實際的數據來設定。比如:源數據中包含了一年的數據,即 day 字段有 365 個值,那麼該參數就需要設置成大於 365,如果使用默認值 100,則會報錯。
hive.exec.max.dynamic.partitions.pernode=100
(5)整個 MR Job 中,最大可以創建多少個 HDFS 文件。
hive.exec.max.created.files=100000
10 、小文件進行合併
在 map 執行前合併小文件,減少 map 數:CombineHiveInputFormat 具有對小文件進行合併的功能(系統默認的格式)。
HiveInputFormat 沒有對小文件合併功能。
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
11、開啓並行執行
Hive 會將一個查詢轉化成一個或者多個階段。這樣的階段可以是 MapReduce 階段、抽樣階段、合併階段、limit 階段。或者 Hive 執行過程中可能需要的其他階段。默認情況下,Hive 一次只會執行一個階段。不過,某個特定的 job 可能包含衆多的階段,而這些階段可能並非完全互相依賴的,也就是說有些階段是可以並行執行的,這樣可能使得整個 job 的執行時間縮短。不過,如果有更多的階段可以並行執行,那麼 job 可能就越快完成。
通過設置參數 hive.exec.parallel 值爲 true,就可以開啓併發執行。不過,在共享集羣中,需要注意下,如果 job 中並行階段增多,那麼集羣利用率就會增加。
set hive.exec.parallel=true; //打開任務並行執行
set hive.exec.parallel.thread.number=16; //同一個 sql 允許最大並行度,默認爲 8。
當然,得是在系統資源比較空閒的時候纔有優勢,否則,沒資源,並行也起不來。
12、嚴格模式
Hive 提供了一個嚴格模式,可以防止用戶執行那些可能意向不到的不好的影響的查詢。
通過設置屬性 hive.mapred.mode 值爲默認是非嚴格模式 nonstrict 。開啓嚴格模式需要
修改 hive.mapred.mode 值爲 strict,開啓嚴格模式可以禁止 3 種類型的查詢。
13、JVM 重用
JVM 重用是 Hadoop 調優參數的內容,其對 Hive 的性能具有非常大的影響,特別是對於很難避免小文件的場景或 task 特別多的場景,這類場景大多數執行時間都很短。
14、推測執行
15、壓縮
TextFile
Hive數據表的默認格式,存儲方式:行存儲。
可使用Gzip,Bzip2等壓縮算法壓縮,壓縮後的文件不支持split
但在反序列化過程中,必須逐個字符判斷是不是分隔符和行結束符,因此反序列化開銷會比SequenceFile高几十倍。
SequenceFile
Hadoop API提供的一種二進制文件,以<key,value>的形式序列化到文件中。存儲方式:行存儲。
支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮。
優勢是文件和hadoop api中的MapFile是相互兼容的
RCFile
存儲方式:數據按行分塊,每塊按列存儲。結合了行存儲和列存儲的優點:
首先,RCFile 保證同一行的數據位於同一節點,因此元組重構的開銷很低
其次,像列存儲一樣,RCFile 能夠利用列維度的數據壓縮,並且能跳過不必要的列讀取
ORCFile
存儲方式:數據按行分塊 每塊按照列存儲
壓縮快 快速列存取
效率比rcfile高,是rcfile的改良版本
總結:
數據倉庫的特點:一次寫入、多次讀取,因此,整體來看,ORCFile相比其他格式具有較明顯的優勢。
TextFile 默認格式,加載速度最快,可以採用Gzip、bzip2等進行壓縮,壓縮後的文件無法split,即並行處理
SequenceFile 壓縮率最低,查詢速度一般,三種壓縮格式NONE,RECORD,BLOCK
RCfile 壓縮率最高,查詢速度最快,數據加載最慢。
16、執行計劃(Explain)
explain select * from emp;
【轉載註明出處,還望尊重原創 】