- 限制输出调整
Limit 语句在很多情况下还是会查询所有数据后才返回部分结果的,可以开启Hive的一个配置属性,这样
在使用limit时可以对数据进行抽样。
set hive.limit.optimize.enable=true
这个设置的缺点是,你可能永远也查不到你有用的数据。
还有两个参数可以控制这个操作
hive.limit.row.max.size=1000000;
hive.limit.optimize.limit.file=10;
- JOIN 优化
Hive的连接是从左到右执行的,查询结果会被放到内存中,所有连接是要将大表放到右边。
如果一个表比较小,完全可以加载到内存中,这样就可以使用map-site JOIN。
set hive.auto.convert.join = true;
set hive.mapjoin.smalltable.filesize=25000000;
- 本地模式
对于hive输入的数据量小时,启动查询,要比执行实际job时间多得多,这样可以让hive在单节点完成处理任务
set hive.exec.mode.local.auto=true;
- 并行执行
Hive执行作业是分阶段的,Hive会将查询计划分成许多阶段,这些阶段有些并不相互依赖,是可以并行执行的。有一个参数可以设定这个属性
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;
- 调整reduce个数
Hive 默认是根据输入数据大小来确定reduce个数的这个设置默认每1G的数据量启动一个reduce
set hive.exec.reducers.bytes.per.reducer=1000000000
有时候可能map端会将数据过滤掉很多,也有可能map端产生数据比实际数据大的多,显然根据输入数据数据量确定reduce个数是不太科学的,这时候可以手工根据实际测试,手动确定reduce个数
set mapred.reduce.tasks=3 (默认值)
set hive.exec.reducers.max=999(默认值,最大reduce个数)
- JVM重用
JVM重用是hadoop的参数,对于hive有很大的性能影响,特别是对于很难避免小文件的场景或task特别多的场景
set mapred.job.resue.jvm.num.tasks=10(jvm 重用次数) (hadoop v1)
mapreduce.job.jvm.numtasks=10 (v2)
缺点是只有任务结束才会释放插槽;
- 调整map个数
protected long computeSplitSize(long blockSize, long minSize,
long maxSize) {
return Math.max(minSize, Math.min(maxSize, blockSize));
}
对于blockSize有hdfs初始化时设定。
我们可以调整分片的大小来调整map任务个数
set mapred.min.split.size=1;(默认)
set mapred.max.split.size=256000000;(默认)
例如
当map任务平均执行时间较长,可以将分片调小增大map任务
set mapred.max.split.size=128000000;
反之亦然。
- Spill AND Sort
map阶段的spill,数据由于内存不足,没有办法一次完成排序,需要将数据先溢出到磁盘中,完成局部排序,spill出的多个文件可以在最后进行merge。可以调整
io.sort.mb = 256 (默认)的值来减少溢出文件但是要注意,要考虑spill的时间成本和merge的时间成本,而且记得不要撑爆内存。
Reduce端的merge也是一样可以用io.sort.factor。一般情况下这两个参数很少需要调整,除非很明确知道这个地方是瓶颈。
- 小文件合并
数据输入前合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并
set mapred.min.split.size.per.node=100000000;(默认值)
一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=100000000;(默认值)
数据输出后合并
set hive.merge.mapfiles =true 在map-only job后合并文件
set hive.merge.mapredfiles =fasle 在map-reduce job后合并文件
set hive.merge.size.per.task=256000000 合并后每个文件的大小
set hive.merge.smallfiles.avgsize=16000000 平均文件大小,决定是否执行合并操作的阈值
- 数据压缩
中间结果压缩
set hive.exec.compress.intermediate=true;
输出结果压缩
当使用CTAS创建表时可以用SequenceFle来存储数据并压缩;
set Hive.default.fileformat = SequenceFile;
set Hive.exec.compress.output = true;
set mapred.output.compression.type = BLOCK;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
- 数据倾斜
map端的combine
set hive.map.aggr=true
对于倾斜数据先不做reduce处理,而是写入到hdfs中,之后重新启动一轮map join来处理数据
默认超过100000条记录的值就是特殊值;
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;