一、hive的随机抓取策略
可以通过 set hive.fetch.task.conversion查看抓取模式
默认是more
有以下三种模式
none | 所有涉及hdfs的读取查询都走mapreduce任务 |
---|---|
mininal | 在进行简单的select *,简单的过滤或涉及分区字段的过滤时走mr |
more | 在mininal模式的基础上,增加了针对查询语句字段进行一些别名的计算操作 |
总结:hive默认是more,在more模式下,简单的查询过滤都不会走mapreduce,
mininal模式下,涉及到分区字段和条件判断会走mapreduce,none模式下,所有涉及到hdfs的查询都会走mapreduce任务
二、本地运行模式
当我们的数据量非常小的时候使用集群模式会很慢,使用本地模式可以加快执行速度
查看是否开启了本地模式
set hive.exec.mode.local.auto
可以设置hive.exec.mode.local.auto 的值为 true开启本地模式
set hive.exec.mode.local.auto=true
注意:开启本地模式后当文件大小小于128M【默认大小】会以本地模式执行,当文件大小大于128M时还是会以集群模式执行
以本地模式执行的任务在yarn上看不到日志
总结:在我们开发测试阶段可以使用本地模式,当产品投入使用使用集群模式
三、并行计算
查看是否开启并行模式
set hive.exec.parallel;
开启并行模式
set hive.exec.parallel=true;
开启并行模式后可以一次执行多条sql语句
例如:
select t1.n1,t2.n2 from (select count(ename) as n1 from emp) t1,(select count(dname) as n2 from dept) t2;
总结: 在一定程度上可以加快执行速度,并不是一次执行的sql语句越多越好,每条sql语句对应一个mapreduce任务,mapreduce任务多了占用的资源就会多,可能会适得其反,一般不会开启并行模式
四、严格模式(理解为增加一些限制)
- hive的严格模式是在严格模式下禁止执行不友好的sql语句
例如
1、查询分区表时不指定分区字段
2、有排序时不使用limit
3、使用笛卡尔积【join】
- 查看严格模式状态
set hive.mapred.mode;
- 开启严格模式
set hive.mapred.mode=strict;
- 关闭严格模式
set hive.mapred.mode=nonstrict;
五、hive排序
- order by 对于查询结果做全排序,只允许有一个reduce处理
所以当我们我们的数据量很大时,使用order by 会使reduce任务压力很大,可能导致任务执行失败
- sort by 会根据我们自己设置的reduce个数,把数据划分到reduce任务中进行排序,只能保证每个reduce输出有序,不能保证全局有序
- distribute by 分区排序,通常结合sort by一起使用,distribute by指定按什么分区,sort by指定每个分区内部按什么排序
- cluster by 相当于distribute by + sort by ,前提是分区字段和排序字段相同
六、Hive join数据倾斜
- 什么是数据倾斜
数据倾斜是当我们reduce个数大于等于二时,某一个reduce任务处理的数据量过大,导致该reduce任务卡住,宕机,挂掉,进而影响整个任务的执行
- 为什么要解决数据倾斜
某一个reduce任务处理的数据量过大,导致该reduce任务卡住,宕机,挂掉,进而影响整个任务的执行
- 怎样解决
- 1、小表关联小表 不用管
- 2、小表join大表 map-join
查看是否开启mapjoin
set hive.auto.convert.join;
解决方法
1、语法糖
select /+MAPJOIN(smallTable)/ smallTable.key bigTable.value from smallTable join bigTable on
2、开启mapjoin
set hive.auto.convert.join=true;
该参数为true的时候,Hive自动对左边的表统计量,如果
是小表,就加入到内存,即对小表使用Mapjoin
3、尽可能使用相同的连接键,如果不同,多一个join就会多开启一个mapreduce,执行速度变得慢
- 3、大表join大表 map-side
大表关联大表时可能会无法避免数据倾斜,但我们可以在map段对数据进行处理
1、空key过滤
若key的内容存在大量的空值,且这些值对结果没有影响时,可以在进去reduce之前把这些空值过滤掉
2、空key转换
若key的内容存在大量的空值,且这些值对结果有影响时,我们可以在key前面打上一个标签,这样打上不同标签的key会进入到一个reduce中,达到负载均衡的效果
但是reduce的结果是带标签的key不是我们想要的结果,这时我们可以再开一个mapredece任务把标签去掉,虽然使用了两个mapreduce任务会很慢,但要好过出不来结果
七、合并小文件
- 1、hadoop不适合存储小文件
- 2、MR不适合处理小文件
- 3、Hive不适合处理小文件
- 文件数目小,容易在文件存储端造成压力,给hdfs造成压力,影响效率
设置合并属性
是否合并map输出文件: hive.merge.mapfiles=true
是否合并reduce输出文件: hive.merge.mapredfiles=true
合并文件的大小: hive.merge.size.per.task=25610001000
去重统计
数据量小的时候无所谓,数据量大的情况下,由于 COUNT DISTINCT操作需要用一个 Reduce Task来完成,
这一个 Reduce需要处理的数据量太大,就会导致整个JOb很难完成,一般 COUNT DISTINCT使用先 GROUP BY再COUNT的方式替换
八、控制map和reduce的数量(一般情况下我们不去动它)
控制Hive中Map以及 Reduce的数量
Map数量相关的参数
mapred.max.split.size;一个split的最大值,即每个map处理文件的最大值
mapred.min.split.size.per.node个节点上split的最小值
mapred.min.split.size.per.rack一个机架上spit的最小值
Reduce数量相关的参数
mapred.reduce.tasks;强制指定reduce任务的数量
hive.exec.reducers.bytes.per.reducer每个reduce任务处理的数据量
hive.exec.reducers.max每个任务最大的reduce数
九、JVM重用
- 当我们的小文件个数过多,task个数过多,需要申请的资源过多的时候,我们可以先申请一部分资源,全部执行完毕后再释放,
比我们申请一个释放一个要快。
set mapred.job.reuse.jvm.num.tasks=n
n为task插槽个数
- 缺点:
设置开启后,task插槽会一直占用资源,无论是否有task进行,直到所有的task,
即整个job全部执行完毕后,才会释放所有的task插槽,所以我们要合理地设置这个n
(比如,我们设置申请了10个,但是现在来了6个,剩下4个插槽会在job全部执行完毕之前一直占用资源)
总结:提前申请资源一定程度上能够加快执行速度,但也可能会造成资源浪费
标签:set,join,reduce,模式,任务,hive,优化 From: https://www.cnblogs.com/w-ll/p/18546859