关于Hive的优化(仅供参考) :
1、关于join中 出现数据倾斜的操作 :
这里我们需要设置两个参数 :
1.1、hive.optimize.skewjoin=true; 解释 : 如果join中出现了数据倾斜,应该设置成true。
1.2、set hive.skewjoin.key=1000000; 解释 : 这是join的键对应的记录条数超过这个值则会进行优化。而这个优化的措施是 : 正常只有一个job来执行任务的,优化后会出现两个job来执行任务。当数据量达到1000000以上的时候 , hive会在启动一个job , 然后将原有的数据的key加上一个随机数将数据打乱。这样数据就会分到不同的节点上去计算。
最后在原有打乱的基础上在做一次运算,然后在启动一个job, 恢复原来的key, 在做一次运算。
2、关于maojoin的操作 :
2.1、其实maojoin的优化很简单, 就是将我们的小表加载到缓存中, 这样所有的节点都可以访问到这个小表(有点像广播变量)。 怎么样开启这种方式呢?
set hive.auto.convert.join=true; 解释: hive.mapjoin.smalltable.filesize默认是25MB。什么意思呢?这个值是自己判断的, 就是当表格文件小于25MB的时候, 会自动启动mapjoin。(建议自己手动启动!)
手动启动方式:select /*+ maojoin(A)*/ f.a,f.b from A t join B f on (f.a=t.b and f.ftime=20110802)
其中A是小表, B是大表, 这样我们是让join发生在map端。
注意 : Mapjoin使用的场景
1、关联操作中有一张小表 2、不等值的连接操作 3、mapjoin最好是手动操作
3、对于bucket join的操作 :
3.1、两个表以相同的方式划分桶。
3,2、两个表的桶的个数是倍数关系。
例子: creat table order(cid int,price float) clustered by (cid) into 30 buckets;
creat table customer(cid int,price string) clustered by (cid) into 60 buckets; select price from order t join customer s on t.cid=s.id;
4、关于where和join的操作 :
4.1、优化前 : select o* from order o join customer c on o.cid=d.id where o.time='2017-01-01'; 优化后 : select o.* from (select cid from order where time='2017-01-01')o join customer c on o.cid=c.id;
解释 :优化前是先join后在where进行过滤的 , 这样并没有减轻reduce的压力。 优化后是在mao端执行where, 过滤数据, 然后在join的。这样大大降低了计算量。
5、关于group by的操作 :
5.1、hive.groupby.skewindata=true; 解释 : 如果group by过程中出现数据倾斜 , 应该设置成true。 5.2、set hive.groupby.maoagger.checkinterval=1000000; 解释 : group 对应的键对应的记录数超过这个值则会进行优化,优化方案跟上面一样, 也会运行来年各个job。
6、对于HIVE表的操作 :
6.1、分区 : '表'相当于一个大目录,分区就是在这个大目录下面创建一个个的小目录。而且分区字段不能是表中已经存在的字段 , 分区的字段不是真实存在的 , 这会显示给你看也可以查询, 但是不会存在表中。
分区分为静态分区和动态分区 : 静态分区 : 就是在建表的时候指定分区。 动态分区 : set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; 下面这个设置的默认值是strict 。 描述 :strict是避免分区字段全部都是动态的 , 也就是至少一个分区字段是有指定值的。我们一般用nonstrict ,就是所有的分区字段都可以是动态的。
7、下面是通过对hive job的优化来优化hive :
7.1、并行化执行 : ive执行过程中的job是按照默认的顺序来执行的,如果没有太大的依赖关系,最好并行执行,减少执行的时间, 每个查询被hive转化成多个阶段,有些阶段关联性不大,则可以并行执行,减少执行时间。 set hive.exec.parallel=true;
set hive.exec.parallel.thread.numbe=16(默认8);
7.2、本地化执行 : 首先开启本地化执行 : set hive.exec.mode.local.auto=true; 当一个job满足如下条件的时候才会真正使用本地模式来执行 :
1、job的输入数据大小必须小于参数 :
hive.exec.mode.local.auto.inputbytes.max (默认是128MB)
2、job的map数必须小于参数:
hive.exec.node.local.auto.tasks.max (默认是4)
3、job的reduce必须是0或者是1。
7.3、job合并输入的小文件
在集群中面临这样的问题, 就是集群中有很多的小文件 , 这样会启动很多的(FileinputFormat会调用getsplit()方法对文件进行split , 而spilt的个数决定了map的个数), 而且这小文件执行的时间短, 甚至还没有我们调用资源用的时间多 , 造成了集群资源的严重浪费。
解决 : set hive.input.format=oar.apache.hadoop.hive.ql.io.CombineHiveInputForma 这样做以后,就会把多个split分片合并成一个。 而合并的文件数由mapred.max.split.size限制的大小来决定
7.4、job合并输出小文件 :
小文件的输出虽然不占用多大的磁盘空间 但是不要忘记无论多小的文件都会在HDFS的namenode上面存在一条元数据记录下来.很浪费资源。
解决 : set hive.merge.smallfiles.avgsize=256000000;当输出文件平均大小小于该值,启动新job合并文件
set hive.merge.size.per.task=64000000;设定合并之后的文件大小
7.5、JVM的重利用 :
JVM的重用是可以使得JVM实例在同一个JOB中重新实用N次
方法 : set mapred.job,reduse.jvm.num.tasks=10;
JVM的重用对hive的性能有很大的影响, 特别是对小文件的场景或者是task特别多场景 , 可以有效地减少执行时间。
7.6、关于数据的压缩 :
两种压缩方式 : 中间压缩和最终压缩 :
中间压缩 ; 减少网络传输的数据量,中间压缩,不需要压缩效果特别好 , 选择一个节省CPU耗时的压缩方式就行。
set hive.exec.compress.intermediate=true;
set hive.intermedia.compression.codec=org.apache.hadoop.io.compress.SnappyCode;
set hive.intermedia.compression.type=BLOCK;(按照块进行压缩)
hive查询的最总输出结果的压缩 : 这个阶段可以选择一个压缩效果比价好的 , 这样可以境地集群存储的数据量, 占用较小的空间。
set hive.exec.compress.ouput=true;
set mapred.output.compresssion.codec=org.apache.hadoop.io.compress.GzipCodec;
set hive.intermedia.compression.type=BLOCK;
仅供参考!