hive优化

一、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全部执行完毕之前一直占用资源)

总结:提前申请资源一定程度上能够加快执行速度,但也可能会造成资源浪费

posted @   w我自横刀向天笑  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示