集群最优配置的最好方式是通过实验测试,然后衡量结果。
普通配置
set hive.metastore.client.socket.timeout=500;
set mapreduce.job.queuename=bigdata;
set mapred.job.name=jobname;
并行化配置
hive默认job是顺序进行的,一个HQL拆分成多个job,job之间无依赖关系也没有相互影响可以并行执行
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=8;
本地化配置:
在存放数据的节点上执行
set hive.exec.mode.local.auto=true;
(1)job的输入数据大小必须小于参数
hive.exec.mode.local.auto.inputbytes.max(默认128MB)
(2)job的map数必须小于参数:
hive.exec.mode.local.auto.tasks.max(默认为4)太多没有足够的slots
(3)job的reduce数必须为0或1
输入小文件配置
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
输出小文件配置
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.merge.smallfiles.avgsize=256000000;
set hive.merge.orcfile.stripe.level=false;
动态分区配置
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
SET hive.exec.max.dynamic.partitions=100000;
SET hive.exec.max.dynamic.partitions.pernode=100000;
insert overwrite table device_open partition(year='2017',month='05',day,hour)
set hive.optimize.sort.dynamic.partition=true;
压缩配置:
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK;
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.intermediate.compression.type=BLOCK;
什么情况使用hive压缩?
(1)在hadoop作业执行过程中,job执行速度更多的是局限于I/O,而不是受制于CPU。
压缩格式?
(1)GZip 和 BZip2压缩格式是所有最近的hadoop版本支持的,而且linux本地的库也支持这种格式的压缩和解压缩。
(2)Snappy是最近添加的压缩格式,可以自己添加这种压缩格式。
(3)LZO是经常用到的压缩格式
压缩优缺点:
(1)GZip 和 BZip2压缩可以保证最小的压缩文件,但是过于消耗时间; Snappy和LZO压缩和解压缩很快,但是压缩的文件较大。所以如何选择压缩格式,需要根据具体的需求决定。(I/O,CPU)
(2)BZip2 and LZO支持压缩文件分割
JVM重利用
set mapred.job.reuse.jvm.num.tasks=20;
map端聚合
set hive.map.aggr=true;
set mapred.map.tasks.speculative.execution=false;
set mapred.reduce.tasks.speculative.execution=false;
set hive.exec.reducers.bytes.per.reducer=256000000;
set hive.exec.max.created.files=100000;
map端JOIN
SET hive.auto.convert.join=true;
SET hive.mapjoin.smalltable.filesize=600000000;
SET hive.auto.convert.join.noconditionaltask=true;
SET hive.auto.convert.join.noconditionaltask.size=10000000;
hive map 优化
set mapred.map.tasks=10
(1)默认map个数
default_num=total_size/block_size;
(2)期望大小(手动设置的个数)
goal_num =mapred.map.tasks;
(3)设置处理的文件大小(根据文件分片大小计算的map个数)
split_size=max(block_size,mapred.min.split.size);
split_num=total_size/split_size;
(4)最终计算的map个数(实际map个数)
compute_map_num=min(split_num,max(default_num,goal_num))
(1)如果想增加map个数,则设置mapred.map.tasks为一个较大的值;
(2)如果想减小map个数,则设置mapred.min.split.size为一个较大的值。
hive shuffle优化
Map 端
set io.sort.mb=100;
set io.sort.spill.percent=0.8
min.num.spill.for.combine
io.sort.factor
io.sort.record.percent
reduce端
mapred.reduce.parallel.copies
mapred.reduce.copy.backoff
io.sort.factor
mapred.job.shuffle.input.buffer.percent
hive reduce优化
set mapred.map.tasks.speculative.execution=false;
set mapred.reduce.tasks.speculative.execution=false;
set mapred.reduce.tasks=10;直接设置
set hive.exec.reducers.max=999;
set hive.exec.reducers.bytes.per.reducer=;
maxReducers=hive.exec.reducers.max
perReducer=hive.exec.reducers.bytes.per.reducer
numRTasks =min[maxReducers,input.size/perReducer]
数据倾斜配置
数据倾斜时负载均衡,当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作
set hive.groupby.skewindata=true;
set hive.groupby.mapaggr.checkinterval =100000;
作业运行内存配置
yarn.scheduler.minimum-allocation-mb
yarn.scheduler.maximum-allocation-mb
yarn.nodemanager.resource.memory-mb
yarn.nodemanager.vmem-pmem-ratio
yarn.scheduler.increment-allocation-mb
set mapreduce.map.memory.mb=8192;
set mapreduce.reduce.memory.mb=8192;
set mapreduce.map.java.opts=-Xmx6144m;
set mapreduce.reduce.java.opts=-Xmx6144m;
抽样查询
SELECT * from numbers TABLESAMPLE(BUCKET 3 OUT OF 10 ONrand()) s;
SELECT * FROM numbers flat TABLESAMPLE(0.1 PERCENT) s;
Hive中小文件问题:
Hive里面什么时候会产生大量小文件呢?
(1)一个大文件使用动态分区,可能导致大量分区产生,从而产生多很多小文件,也会导致很多的mapper
(2)Reduce个数越多,小文件越多,Reduce个数和输出文件是一样的
(3)数据源本身就包含很多的小文件
解决小文件的问题
(1)果动态分区不可预知的情况下,最好别用,如果用也最好distributedby 分区字段,这样我们知道会对字段进行一个hash操作,这样就会把相同的相同的分区给同一个Reduce去处理
(2)如果Reduce数量太多,则减少reduce的数量
(3)进行一些参数设置,设置 mapper输入文件合并一些参数
动态分区插入时OOM问题
(1)修改参数hive.optimize.sort.dynamic.partition为true。产生OOM问题的原因是同时打开了太多写分区的record,
writer同时写入文件,开启该参数的话,分区列会全局排序,使得reduce端每个分区只有一个文件写入,降低reduce的内存压力
(2)要是还报OOM问题,进一步可以考虑调整map、reduce的内存大 mapreduce.map.memory.mb 和 mapreduce.reduce.memory.mb 参数
常用函数-时间函数
SUBSTR(CURRENT_TIMESTAMP(), 1, 19) AS MAKE_TIME
datediff(endDate, startDate)
where datediff(current_timestamp,create_time)<=30;
date_add('2016-12-29',10); 2017-01-08
date_sub('2016-12-29',10); 2016-12-19