2021年大数据Hive(十一):Hive调优
全網最詳細的大數據Hive文章系列,強烈建議收藏加關注!
新文章都已經列出歷史文章目錄,幫助大家回顧前面的知識重點。
目錄
系列歷史文章
前言
Hive調優
一、本地模式
1、空key處理
二、SQL優化
1、Group By
2、Count(distinct)
3、笛卡爾積
三、并行執行
四、嚴格模式
五、存儲方式和壓縮方式
系列歷史文章
2021年大數據Hive(十二):Hive綜合案例!!!???????
2021年大數據Hive(十一):Hive調優
2021年大數據Hive(十):Hive的數據存儲格式
2021年大數據Hive(九):Hive的數據壓縮???????
2021年大數據Hive(八):Hive自定義函數
2021年大數據Hive(七):Hive的開窗函數
2021年大數據Hive(六):Hive的表生成函數
2021年大數據Hive(五):Hive的內置函數(數學、字符串、日期、條件、轉換、行轉列)
2021年大數據Hive(四):Hive查詢語法
2021年大數據Hive(三):手把手教你如何吃透Hive數據庫和表操作(學會秒變數倉大佬)
2021年大數據Hive(二):Hive的三種安裝模式和MySQL搭配使用
2021年大數據Hive(一):Hive基本概念
前言
?2021大數據領域優質創作博客,帶你從入門到精通,該博客每天更新,逐漸完善大數據各個知識體系的文章,幫助大家更高效學習。
有對大數據感興趣的可以關注微信公眾號:三幫大數據
Hive調優
一、本地模式
大多數的Hadoop Job是需要Hadoop提供的完整的可擴展性來處理大數據集的。不過,有時Hive的輸入數據量是非常小的。在這種情況下,為查詢觸發執行任務時消耗可能會比實際job的執行時間要多的多。對于大多數這種情況,Hive可以通過本地模式在單臺機器上處理所有的任務。對于小數據集,執行時間可以明顯被縮短。
用戶可以通過設置hive.exec.mode.local.auto的值為true,來讓Hive在適當的時候自動啟動這個優化。
set?hive.exec.mode.local.auto=true;? --開啟本地mr--設置local mr的最大輸入數據量,當輸入數據量小于這個值時采用local? mr的方式,默認為134217728,即128Mset?hive.exec.mode.local.auto.inputbytes.max=51234560;--設置local mr的最大輸入文件個數,當輸入文件個數小于這個值時采用local mr的方式,默認為4set?hive.exec.mode.local.auto.input.files.max=10;
案例實操:
--1)開啟本地模式,并執行查詢語句hive (default)>?set?hive.exec.mode.local.auto=true;hive (default)>?select?*?from?score cluster?by?sid;18?rows?selected (1.568?seconds)--2)關閉本地模式,并執行查詢語句hive (default)>?set?hive.exec.mode.local.auto=false;?hive (default)>?select?*?from?score cluster?by?sid;18?rows?selected (11.865?seconds)
1、空key處理
1)空KEY過濾
有時join超時是因為某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾。例如key對應的字段為空,操作如下:
環境準備:
create?table?ori(id bigint,?time?bigint,?uid?string,?keyword string,?url_rank int,?click_num int,?cl/ick_url string)?row?format?delimited fields terminated by?'\t';create?table?nullidtable(id bigint,?time?bigint,?uid?string,?keyword string,?url_rank int,?click_num int,?click_url string)?row?format?delimited fields terminated by?'\t';create?table?jointable(id bigint,?time?bigint,?uid?string,?keyword string,?url_rank int,?click_num int,?click_url string)?row?format?delimited fields terminated by?'\t';load data?local?inpath '/export/data/hivedatas/hive_big_table/*'?into?table?ori;?load data?local?inpath '/export/data/hivedatas/hive_have_null_id/*'?into?table?nullidtable;
不過濾:
INSERT?OVERWRITE TABLE?jointableSELECT?a.*?FROM?nullidtable a JOIN?ori b ON?a.id =?b.id;結果:No?rows?affected (152.135?seconds)
過濾:
INSERT?OVERWRITE TABLE?jointableSELECT?a.*?FROM?(SELECT?*?FROM?nullidtable WHERE?id IS?NOT?NULL?)?a JOIN?ori b ON?a.id =?b.id;結果:No?rows?affected (141.585?seconds)
2)空key轉換
有時雖然某個key為空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key為空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上。例如:
不隨機分布:
set?hive.exec.reducers.bytes.per.reducer=32123456;set?mapreduce.job.reduces=7;INSERT?OVERWRITE TABLE?jointableSELECT?a.*FROM?nullidtable aLEFT?JOIN?ori b ON?CASE?WHEN?a.id IS?NULL?THEN?'hive'?ELSE?a.id END?=?b.id;No?rows?affected (41.668?seconds)???52.477
結果:這樣的后果就是所有為null值的id全部都變成了相同的字符串,及其容易造成數據的傾斜(所有的key相同,相同key的數據會到同一個reduce當中去)
為了解決這種情況,我們可以通過hive的rand函數,隨記的給每一個為空的id賦上一個隨機值,這樣就不會造成數據傾斜
隨機分布:
set?hive.exec.reducers.bytes.per.reducer=32123456;set?mapreduce.job.reduces=7;INSERT?OVERWRITE TABLE?jointableSELECT?a.*FROM?nullidtable aLEFT?JOIN?ori b ON?CASE?WHEN?a.id IS?NULL?THEN?concat('hive',?rand())?ELSE?a.id END?=?b.id;No?rows?affected (42.594?seconds)
二、SQL優化
1、Group By
默認情況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了。
并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端進行部分聚合,最后在Reduce端得出最終結果。
開啟Map端聚合參數設置
--(1)是否在Map端進行聚合,默認為Trueset?hive.map.aggr =?true;--(2)在Map端進行聚合操作的條目數目set?hive.groupby.mapaggr.checkinterval =?100000;--(3)有數據傾斜的時候進行負載均衡(默認是false)set?hive.groupby.skewindata =?true;
當選項設定為 true,生成的查詢計劃會有兩個MR Job。第一個MR Job中,Map的輸出結果會隨機分布到Reduce中,每個Reduce做部分聚合操作,并輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的數據結果按照Group By Key分布到Reduce中(這個過程可以保證相同的Group By Key被分布到同一個Reduce中),最后完成最終的聚合操作。
???????2、Count(distinct)
數據量小的時候無所謂,數據量大的情況下,由于COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換:
方式1:
SELECT?count(DISTINCT?id)?FROM?bigtable;
方式2
SELECT?count(id)?FROM?(SELECT?id FROM?bigtable GROUP?BY?id)?a;
雖然會多用一個Job來完成,但在數據量大的情況下,這個絕對是值得的。
???????3、笛卡爾積
盡量避免笛卡爾積,即避免join的時候不加on條件,或者無效的on條件,Hive只能使用1個reducer來完成笛卡爾積。
???????三、并行執行
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。
當然,得是在系統資源比較空閑的時候才有優勢,否則,沒資源,并行也起不來。
四、嚴格模式
Hive提供了一個嚴格模式,可以防止用戶執行那些可能意向不到的不好的影響的查詢。
通過設置屬性hive.mapred.mode值為默認是非嚴格模式nonstrict 。開啟嚴格模式需要修改hive.mapred.mode值為strict,開啟嚴格模式可以禁止3種類型的查詢。
set?hive.mapred.mode?=?strict;??--開啟嚴格模式set?hive.mapred.mode?=?nostrict;?--開啟非嚴格模式
配置文件修改:
<property><name>hive.mapred.mode</name><value>strict</value></property>
1)對于分區表,在where語句中必須含有分區字段作為過濾條件來限制范圍,否則不允許執行。換句話說,就是用戶不允許掃描所有分區。進行這個限制的原因是,通常分區表都擁有非常大的數據集,而且數據增加迅速。沒有進行分區限制的查詢可能會消耗令人不可接受的巨大資源來處理這個表。
2)對于使用了order by語句的查詢,要求必須使用limit語句。因為order by為了執行排序過程會將所有的結果數據分發到同一個Reducer中進行處理,強制要求用戶增加這個LIMIT語句可以防止Reducer額外執行很長一段時間。
3)限制笛卡爾積的查詢。對關系型數據庫非常了解的用戶可能期望在執行JOIN查詢的時候不使用ON語句而是使用where語句,這樣關系數據庫的執行優化器就可以高效地將WHERE語句轉化成那個ON語句。不幸的是,Hive并不會執行這種優化,因此,如果表足夠大,那么這個查詢就會出現不可控的情況。
??????????????五、存儲方式和壓縮方式
大數據場景下存儲格式壓縮格式尤為關鍵,可以提升計算速度,減少存儲空間,降低網絡io,磁盤io,所以要選擇合適的壓縮格式和存儲格式,存儲方式和壓縮方式之前已經講過,這里不再描述。
- 📢博客主頁:https://lansonli.blog.csdn.net
- 📢歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
- 📢本文由 Lansonli 原創,首發于 CSDN博客🙉
- 📢大數據系列文章會每天更新,停下休息的時候不要忘了別人還在奔跑,希望大家抓緊時間學習,全力奔赴更美好的生活?
總結
以上是生活随笔為你收集整理的2021年大数据Hive(十一):Hive调优的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女友问粉丝过万如何庆祝,我发万字长文《保
- 下一篇: 2021年大数据Hive(十二):Hiv