HiveSQL运行优化参数配置
?
HiveSQL運行優化參數配置
HiveSQL常用數據處理語句
HiveSQL中復雜數據類型操作
?
? ? ? ?我們平時在使用hive執行一些SQL任務時。經常會遇到執行速度很慢,數據傾斜,資源不夠用等問題。那是因為我們沒有合理的使用hive。hive 的主要配置文件為conf中hive-site.xml,里面包含許多配置參數,靈活的根據業務進行相關的參數配置,可以解決以上問題。下面將介紹hive的全部參數的意義以及如何配置。
目錄
常規優化配置
Map的任務數配置
Reduce的任務數配置
其他可選配置
常規優化配置
--hive任務配置參數 set mapreduce.job.queuename=default; set mapred.job.name=one_big_job;set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; SET hive.exec.max.dynamic.partitions=1000000; SET hive.exec.max.dynamic.partitions.pernode=1000000; set hive.exec.max.created.files=6553500;set mapred.max.split.size=202400000; set mapred.min.split.size.per.node=202400000; set mapred.min.split.size.per.rack=202400000;set mapred.reduce.tasks=200; set hive.exec.reducers.max=200;set hive.exec.parallel=true; set hive.exec.parallel.thread.number=24;set hive.groupby.skewindata=true; set hive.map.aggr=true;以上參數可以直接配置使用,詳細的參數解釋及最優數值大小參考如下。
?
Map的任務數配置
執行任務時Map的任務數配置,即執行任務時,上圖標紅的,number of mappers: 1 的數量。
map的個數設置其實對執行效率有很大的影響:
- 如果mappers數量過多,map任務啟動和初始化的時間遠遠大于邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的map數是受限的;
- 如果mappers數量過少,Hadoop的計算資源沒有充分的利用,計算緩慢;
map的個數主要的決定因素有: input的文件總個數,input的文件大小,集群設置的文件塊大小(默認為128M)
map個數的計算公式如下:splitsize=max(minimumsize,min(maximumsize,blocksize))
如果沒有設置minimumsize和maximumsize,splitsize的大小默認等于blocksize
計算過程可以簡化為如下的公式,詳細算法可以參照FileInputSplit類中的getSplits方法
total_split ;
for(file :輸入目錄中的每個文件)
{
file_split = 1;
if(file.size>splitsize)
{
file_split=file_size/splitsize;
}
total_split+=file_split;
}
由于mapreduce中沒有辦法直接控制map數量,所以只能通過設置每個map中處理的數據量進行設置;reduce是可以直接設置的
set mapred.max.split.size = 256000000;? (200M = 200 * 1000 * 1000)
-----決定每個map處理的最大的文件大小,單位為B
?
set mapred.min.split.size.per.node = 256000000; ? ? ? ??
-----節點中可以處理的最小的文件大小
set mapred.min.split.size.per.rack = 256000000; ? ? ? ??
-----機架中可以處理的最小的文件大小
Reduce的任務數配置
執行任務時 reducers 的任務數配置,即執行任務時,上圖標紅的,number of reducers: 159 的數量。
影響:reduce的個數設置其實對執行效率有很大的影響:
- 如果reduce太少,如果數據量很大,會導致這個reduce異常的慢,從而導致這個任務不能結束,也有可能會OOM;
- 如果reduce太多,產生的小文件太多,合并起來代價太高,namenode的內存占用也會增大;
reduce個數可以由以下三個參數直接決定:
set mapred.reduce.tasks=200;
-----這個參數如果指定了,hive就不會用它的estimation函數來自動計算reduce的個數,而是用這個參數來啟動reducer。默認是-1,根據計算數量的大小來設定,一般設置為200,執行任務是reduce任務數即為200;
set hive.exec.reducers.bytes.per.reducer =?500000000;(500M = 500 * 1000?* 1000)
-----默認是1G,輸入文件如果是10G,那么就會起10個reducer,,單位為B;
set hive.exec.reducers.max=200;
-----這個參數控制最大的reducer的數量,如果輸入文件大小/hive.exec.reducers.bytes.per.reducer 所得出的大小?max ?則會啟動這個參數所指定的reduce個數;?這個并不會影響mapre.reduce.tasks參數的設置,默認的max是999;
其他可選配置
常規配置
set mapreduce.job.queuename=default;
-----設置任務運行隊列,同一個Hadoop集群不同的隊列資源的相互隔離的,避免因大任務計算導致資源耗竭;
set mapred.job.name=one_big_job;
------設置任務運行任務名稱,在yarn的任務日志頁面可以現在此 Jobname;
set mapreduce.task.timeout = 60000
-----mr程序的task執行情況匯報過期時間,默認60000(10分鐘),設置為0表示不進行該值的判斷。
set hive.cli.print.current.db=true;
-----讓提示符顯示當前庫
set hive.cli.print.header=true;
-----顯示查詢結果時顯示字段名稱:
?
動態分區插入數據參數配置
set hive.exec.dynamic.partition=true;
-----是開啟動態分區,即動態插入分區,可以根據數據計算結果值為分區;
set hive.exec.dynamic.partition.mode=nonstrict;
-----這個屬性默認值是strict,就是要求分區字段必須有一個是靜態的分區值;
set hive.exec.max.dynamic.partitions=1000000;
-----每一個mapreduce job允許創建的分區的最大數量,如果超過了這個數量就會報錯,缺省值100;
set hive.exec.max.dynamic.partitions.pernode=1000000;
-----一個dml語句允許創建的所有分區的最大數量,缺省值1000;
set hive.exec.max.created.files=6553500;
-----所有的mapreduce job允許創建的文件的最大數量,缺省值100000;
?
作業有多個可并行的job時,設置任務并行及并行個數:
set hive.exec.parallel=true;
-----開啟任務并行執行
set hive.exec.parallel.thread.number=8;
-----同一個sql允許并行任務的最大線程數?
針對一條HiveSQL中存在的查詢操作無直接關聯,可以并行執行,如union all操作,可以開啟并行執行;left join類的操作則語句配置失效,本身不能進行并行執行,存在依賴;
多條獨立HiveSQL需要并行執行,可以同時提交任務,與HvieSQL這里的配置沒有關系;
?
配置任務執行引擎
set hive.execution.engine=mr; (默認)
set hive.execution.engine=tez;(需要Hadoop集群安裝/支持)
set hive.execution.engine=spark;
如果設置執行引擎為mr,那么就會調用Hadoop的maprecude來運行需要執行job的程序;
如果設置執行引擎為spark,那么就會調用spark來執行任務。有條件的話,就設置執行引擎為Spark,運行的比Hadoop的MapReduce快了很多。
如果設置執行引擎為tez,Tez是一個Hive的運行引擎(需要先安裝Tez),性能優于MR,Tez基于內存的計算使得hive可以有更高的運算效率。
?
小表數據關聯計算使用mapjoin
set hive.auto.convert.join = true;
-----是否自動轉換為mapjoin
set hive.mapjoin.smalltable.filesize=50000000;
-----小表的最大文件大小,默認為25*000*000,即25M
set hive.auto.convert.join.noconditionaltask = true;
-----是否將多個mapjoin合并為一個
set hive.auto.convert.join.noconditionaltask.size = 10000000; (10*1000*1000)
-----多個mapjoin轉換為1個時,所有小表的文件大小總和的最大值。
MapJoin顧名思義,就是在Map階段進行表之間的連接。而不需要進入到Reduce階段才進行連接。這樣就節省了在Shuffle階段時要進行的大量數據傳輸。從而起到了優化作業的作用。
MapJoin適用的場景:mapjoin的適用場景如關聯操作中有一張表非常小,.不等值的鏈接操作。通過上面分析你會發現,并不是所有的場景都適合用MapJoin. 它通常會用在如下的一些情景:在二個要連接的表中,有一個很大,有一個很小,這個小表可以存放在內存中而不影響性能。這樣我們就把小表文件復制到每一個Map任務的本地,再讓Map把文件讀到內存中待用。
?
數據傾斜
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 中),最后完成最終的聚合操作。
set hive.map.aggr=true;
-----在map中會做部分聚集操作,效率更高但需要更多的內存。
如果以上不管用,可以對傾斜的數據進行單獨的sql處理。
?
內存溢出優化
Hadoop處理數據時,出現內存溢出的處理方法(內存調優),Mapper/Reducer階段JVM內存溢出,堆內存不足時,一般會拋出如下幾種異常:
java.lang.OutOfMemoryError:” GC overhead limit exceeded
Error: Java heapspace
running beyondphysical memory limits.Current usage: 4.3 GB of 4.3 GBphysical memoryused; 7.4 GB of 13.2 GB virtual memory used. Killing container
Exception: java.lang.OutOfMemoryError thrown from theUncaughtExceptionHandler in thread
Socket Reader #1 for port 30703
Halting due to Out Of Memory Error...
Halting due to Out Of Memory Error...
Halting due to Out Of Memory Error...
java.lang.OutOfMemoryError:Direct buffffer memory
目前MapReduce主要通過兩個組參數去控制內存:(將如下參數調大)
mapreduce.map.java.opts=-Xmx2048m
-----默認參數,表示jvm堆內存,注意是mapreduce不是mapred
mapreduce.map.memory.mb=2304
-----container的內存
mapreduce.reduce.java.opts=-Xmx2048m
-----默認參數,表示jvm堆內存
mapreduce.reduce.memory.mb=2304
-----container的內存
?
HiveSQL執行命令
hive -e 'select * from area where code=202020' >> /root/files/a.csv
hive -f ?sqlfile.sql >> ? /files/result.csv
hive -hiveconf day=2015 -f sqlfile.sql >> ?/files/result.csv
-----傳入一個參數
hive -hiveconf year=2015 -hiveconf month=09 -hiveconf day=11 ?-f sqlfile.sql >> ?/files/result.csv
-----傳入多個參數
nohub???hive??-f??sqlfile.sh??>>??result.csv??2>&1 &
-----后臺執行
?
Hive中引入外部包
hive默認的函數并不是太完整,以后我們使用的使用肯定需要自己補充一些自定義函數的。
ADD jar hdfs://ip:9000/user/hadoop/share/HiveUdf.jar;
-----在hive中添加包
delete?jar?hdfs://ip:9000/user/hadoop/share/HiveUdf.jar;
-----在hive中刪除包
CREATE TEMPORARY FUNCTION tmp_fun as 'com.hive.udf.Encry';
-----在hive中創建函數
select tmp_fun('123');
-----在hive中使用函數
?
Hive中數據壓縮
中間壓縮處理hive查詢的多個job之間的數據,對于中間壓縮,最好選擇一個節省cpu耗時的壓縮方式
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.intermediate.compression.type=BLOCK;
-----按塊壓縮,而不是記錄?
最終輸出壓縮(選擇壓縮效果好的,減少儲存空間)?
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK;
-----按塊壓縮,而不是記錄?
?
?
?
?
總結
以上是生活随笔為你收集整理的HiveSQL运行优化参数配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 决策树-缺失值和连续值处理及属性划分
- 下一篇: HiveSQL常用数据处理语句