
image.png
工作中常用的 hive 參數(shù)調(diào)優(yōu),整理如下。
原則:
? 最少數(shù)據(jù)
? 最少字段
? 最少Job數(shù)
? 最少讀取次數(shù)
? 避免數(shù)據(jù)傾斜
? 整體最優(yōu)而不是局部最優(yōu)
? JVM 內(nèi)存
文件大小合理切分
這里需要結(jié)合集群的資源來合理的設(shè)置切片大小。
# 文件分割大小
set mapreduce.input.fileinputformat.split.maxsize=536870912;
# 節(jié)點(diǎn)文件分割大小
set mapreduce.input.fileinputformat.split.minsize.per.node=536870912;
# 機(jī)架文件分割大小
set mapreduce.input.fileinputformat.split.minsize.per.rack=536870912;
# Reduce 文件分割大小
set hive.exec.reducers.bytes.per.reducer=536870912;
# 輸入合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
# 在Map-only的任務(wù)結(jié)束時(shí)合并小文件
set hive.merge.mapfiles=true;
# 在Map-reduce結(jié)束時(shí)合并小文件,(注:如果文件壓縮格式不一致必須設(shè)置為false)
set hive.merge.mapredfiles=true;
# 合并文件的大?。J(rèn))
set hive.merge.size.per.task=104857600;
# 當(dāng)輸出文件的平均大小小于該值時(shí),啟動(dòng)一個(gè)獨(dú)立的map-reduce任務(wù)進(jìn)行文件merge(默認(rèn))
set hive.merge.smallfiles.avgsize=104857600;
最小數(shù)據(jù)
最小數(shù)據(jù)原則:(map階段,shuffle階段,reduce階段)
- 網(wǎng)絡(luò)開銷:map端在寫磁盤的時(shí)候采用壓縮的方式將map的輸出結(jié)果進(jìn)行壓縮是一個(gè)減少網(wǎng)絡(luò)開銷很有效的方法
- 數(shù)據(jù)集大?。?/li>
# 數(shù)據(jù)先過濾后使用
# Shuffle操作
# Hive Group By查詢中是否在Map端先進(jìn)行聚合
set hive.map.aggr=true;
# Spill、Meger文件進(jìn)行壓縮
set mapreduce.map.output.compress=true;
# 壓縮編解碼器的類名
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
數(shù)據(jù)傾斜
是否啟用傾斜連接優(yōu)化
set hive.optimize.skewjoin=true;
開啟并行
# 開啟任務(wù)并行執(zhí)行
set hive.exec.parallel=true;
# 允許并行任務(wù)的最大線程數(shù)
set hive.exec.parallel.thread.number=16;
# 默認(rèn)情況下,當(dāng)整個(gè)MapReduce作業(yè)的所有已執(zhí)行完成的Map Task任務(wù)數(shù)超過Map
# Task總數(shù)的 mapreduce.job.reduce.slowstart.completedmaps (默認(rèn)為0.05) 后,ApplicationMaster便會(huì)開始調(diào)度執(zhí)行Reduce Task任務(wù)。
set mapreduce.job.reduce.slowstart.completedmaps=0.05
# 個(gè)MapOutputCopier線程到已完成的Map Task任務(wù)節(jié)點(diǎn)上分別copy一份屬于自己的數(shù)據(jù)。
# 這些copy的數(shù)據(jù)會(huì)首先保存的內(nèi)存緩沖區(qū)中,當(dāng)內(nèi)沖緩沖區(qū)的使用率達(dá)到一定閥值后,則寫到磁盤上。
set mapred.reduce.parallel.copies=5
內(nèi)存優(yōu)化
1.JVM進(jìn)程跑在 container 中,mapreduce.map.java.opts 能夠通過Xmx設(shè)置JVM最大的heap的使用,一般設(shè)置為 0.75 倍的 mapreduce.map.memory.mb ,因?yàn)樾枰獮?Java code,非JVM內(nèi)存使用等預(yù)留些空間;reduce的內(nèi)存設(shè)置同理。
# 設(shè)置環(huán)形緩沖區(qū)的大小,經(jīng)過map處理后的鍵值對(duì),不會(huì)立馬寫入磁盤,
# 而是暫時(shí)保存在內(nèi)存中的MapOutputBuffe內(nèi)部的環(huán)形數(shù)據(jù)緩沖區(qū)
set mapreduce.task.io.sort.mb=1024
# 開始 spill 的百分比
set mapreduce.map.sort.spill.percent=0.8
# 設(shè)置 Map 的內(nèi)存大小以及 JVM Heap
set mapreduce.map.memory.mb=4096
set mapreduce.map.java.opts=-Xmx3072M
# 設(shè)置 Reduce 的內(nèi)存大小以及 JVM Heap
set mapreduce.reduce.memory.mb=4096
set mapreduce.reduce.java.opts=-Xmx3072M
# shuffile在reduce內(nèi)存中的數(shù)據(jù)最多使用內(nèi)存量
mapred.job.shuffle.input.buffer.percent=0.7
磁盤優(yōu)化
磁盤的頻繁IO也是一種不小的消耗,所以可以通過配置一些參數(shù)來減少磁盤的IO
# 默認(rèn)代表進(jìn)行merge的時(shí)候最多能同時(shí)merge多少spill
# 如果有100個(gè)spill個(gè)文件,此時(shí)就無(wú)法一次完成整個(gè)merge的過程
# 這個(gè)時(shí)候需要調(diào)大來減少merge的次數(shù),從而減少磁盤的操作;
set mapreduce.task.io.sort.factor=10
# Combiner存在的時(shí)候,此時(shí)會(huì)根據(jù)Combiner定義的函數(shù)對(duì)map的結(jié)果進(jìn)行合并,什么時(shí)候進(jìn)行Combiner操作呢???
# 和Map在一個(gè)JVM中,是由min.num.spill.for.combine的參數(shù)決定的,默認(rèn)是3,
# 也就是說spill的文件數(shù)在默認(rèn)情況下由三個(gè)的時(shí)候就要進(jìn)行combine操作,最終減少磁盤數(shù)據(jù);
set min.num.spill.for.combine=3
# 減少磁盤IO和網(wǎng)絡(luò)IO還可以進(jìn)行:壓縮,對(duì)spill,merge文件都可以進(jìn)行壓縮。
# 中間結(jié)果非常的大,IO成為瓶頸的時(shí)候壓縮就非常有用,可以通過mapreduce.map.output.compress(default:false)設(shè)置為true進(jìn)行壓縮,
# 數(shù)據(jù)會(huì)被壓縮寫入磁盤,讀數(shù)據(jù)讀的是壓縮數(shù)據(jù)需要解壓,在實(shí)際經(jīng)驗(yàn)中Hive在Hadoop的運(yùn)行的瓶頸一般都是IO而不是CPU,壓縮一般可以10倍的減少IO操作,
# 壓縮的方式Gzip,Lzo,BZip2,Lzma等,其中Lzo是一種比較平衡選擇,mapreduce.map.output.compress.codec(default:org.apache.hadoop.io.compress.DefaultCodec)參數(shù)設(shè)置。
# 但這個(gè)過程會(huì)消耗CPU,適合IO瓶頸比較大。
set mapreduce.map.output.compress=true
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec
資源參數(shù)
# 指定資源隊(duì)列,root.urgent
set mapred.job.queue.name=root.default;
# 最小可申請(qǐng)內(nèi)存量
set yarn.scheduler.minimum-allocation-mb=1024;
# 最大可申請(qǐng)內(nèi)存量
set yarn.scheduler.maximum-allocation-mb=32768;
# 最小可申請(qǐng)CPU數(shù)
set yarn.scheduler.minimum-allocation-vcores=1;
# 最大可申請(qǐng)CPU數(shù)
set yarn.scheduler.maximum-allocation-vcores=16;
# AM Container Heap內(nèi)存大小
set yarn.app.mapreduce.am.command-opts=-Xmx2048M;
# AM Container內(nèi)存大小
set yarn.app.mapreduce.am.resource.mb=4096;
# NodeManger可用內(nèi)存大小
set yarn.nodemanager.resource.memory-mb=57344;
# NodeManger可用CPU數(shù)
set yarn.nodemanager.resource.cpu-vcores=16;