企业级hive优化学习

企业级hive优化学习


目录

企业级hive优化学习

1.fetch抓取

2.本地模式

3.小表join大表

4.大表Join大表

5.MapJoin

6.group by 优化

7.Count(Distinct)去重统计

8.笛卡尔积避免

9.行列优先过滤

10.通过控制进程数预防数据倾斜

11.并行执行

12.严格模式,建议默认

13.JVM重用

14.推测执行

15.压缩


1.fetch抓取

  1. 介绍:Hive在某些情况可不必使用mapreduce计算,如一个目录下文件的select *,就是读取而已。
  2. 更改操作:jdbc:hive2://hadoop102:10000>set hive.fetch.task.conversion=more;
  3. 内容配置:/conf/hive-default.xml 2640行    hive.fetch.task.conversion :
    1. none(全部默认是mapreduce)
    2. minimal
    3. more(高版本默认使用)
 
    hive.fetch.task.conversion
    more
    
      Expects one of [none, minimal, more].
      Some select queries can be converted to single FETCH task minimizing latency.
      Currently the query should be single sourced not having any subquery and should not have
      any aggregations or distincts (which incurs RS), lateral views and joins.
      0. none : disable hive.fetch.task.conversion
      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
      2. more    : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
    
  

2.本地模式

  1. 数据量非常小时,本地模式可以明显减少执行时间,默认关闭;
  2. 通过hive.exec.mode.local.auto的值设为true,来让Hive在适当时候自动启动优化(默认小于128M,4个);
  3. 在hive中修改最大输入文件大小和数量
    1. set hive.exec.mode.local.auto.inputbytes.max=134217728;
    2. set hive.exec.mode.local.auto.input.foles.max=10;
    3. set hive.exec.mode.local.auto=true;

3.小表join大表

  1. hive会将小表进行缓存
  2. 事实上,“把小表放在前面做关联可以提高效率”这种说法,是错误的。
  3. 正确的说法应该是“把重复关联键少的表放在join前面做关联可以提高join的效率。”
  4.  例如A表id=3有1条记录,B表id=3有10条记录。首先读取v[0]发现是A表的记录,用了1次读取操作。然后再读取v[1]发现是B表的操作,这时v[0]和v[1]可以直接关联输出了,累计用了2次操作。这时候reduce已经知道从v[1]开始后面都是B 表的记录了,因此可以直接用v[0]依次和v[2],v[3]……v[10]做关联操作并输出,累计用了11次操作。

  5. 换过来,假设A表id=3有10条记录,B表id=3有1条记录。首先读取v[0]发现是A表的记录,用了1次读取操作。然后再读取v[1]发现依然是A表的记录,累计用了2次读取操作。以此类推,读取v[9]时发现还是A表的记录,累计用了10次读取操作。然后读取最后1条记录v[10]发现是B表的记录,可以将v[0]和v[10]进行关联输出,累计用了11次操作。接下来可以直接把v[1]~v[9]分别与v[10]进行关联输出,累计用了20次操作。

  6. 额外提一下,当reduce检测A表的记录时,还要记录A表同一个key的记录的条数,当发现同一个key的记录个数超过hive.skewjoin.key的值(默认为1000000)时,会在reduce的日志中打印出该key,并标记为倾斜的关联键。

    最终得出的结论是:写在关联左侧的表,每有1条重复的关联键时,底层就会多1次运算处理。

    假设A表有一千万个id,平均每个id有3条重复值,那么把A表放在前面做关联就会多做三千万次的运算处理,这时候谁写在前谁写在后就看出性能的差别来了

4.大表Join大表

有时某些key对应的数据过多,而相同key对性的数据都会发送到相同的reducer上,从而导致内存不够。

1)空key过滤

-- 改前:
insert overwrite table jointable
select n.* 
from nullidtable n 
left join bigtable o on n.id=o.id;
-- 改后:
insert overwrite table jointable
select n.* 
from (select * from nullidtable where id is not null) n 
left join bigtable o on n.id=o.id;

2)空key转换(数据还需保留)

注意:赋一个随机值时,对hive语句优化的不是时间,是数据倾斜。

-- 改前:
insert overwrite table jointable
select n.* 
from nullidtable n 
full join bigtable o on 
n.id=o.id;
-- 改后:
insert overwrite table jointable
select n.* 
from nullidtable n 
full join bigtable o on 
case when n.id is null then concat('hive',rand()) else 
n.id=o.id;

5.MapJoin

Hive的MapJoin,在Join 操作在 Map 阶段完成,如果需要的数据在 Map 的过程中可以访问到则不再需要Reduce。
小表关联一个超大表时,容易发生数据倾斜,可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。

参数设置:

1)如果是小表,自动选择Mapjoin:

set hive.auto.convert.join = true; -- 默认为false

该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对 小表使用Map join

2)设置大表小表的阀值:

set hive.mapjoin.smalltable.filesize;

hive.mapjoin.smalltable.filesize=25000000   # 默认值是25mb

3)map join做group by 操作时,可以使用多大的内存来存储数据,如果数据太大,则不会保存在内存里

set hive.mapjoin.followby.gby.localtask.max.memory.usage; -- 默认值:0.55

4)本地任务可以使用内存的百分比

set hive.mapjoin.localtask.max.memory.usage; -- 默认值: 0.90

---------------------
作者:kwu_ganymedehttps://blog.csdn.net/kwu_ganymede/article/details/51365002?utm_source=copy
来源:CSDN
原文:
版权声明:本文为博主原创文章,转载请附上博文链接!

6.group by 优化

在map端进行部分聚合,以起到group by优化

set hive.map.aggr = true -- 是否在map端开启聚合,默认为true

set hive.groupby.mapaggr.checkinterval = 100000 -- 在map端进行聚合操作的条目数目

set hive.groupby.skewindata = true -- 有数据倾斜时候进行负载均衡(默认是false) 

相当于combiner,由于combiner会消耗进程,会生成两个mr job:

  1. 第一步MR Job中,Map输出结果全部随机分布到Reduce中,在每个Reduce分别做聚合,并输出结果;
  2. 第二步MR Job会根据第一步预处理后的结果,再按照Group By Key分布到Reduce中,最后完成最终的聚合操作;

7.Count(Distinct)去重统计

需要用一个reduce Task 来完成,一般count distinct 使用先group by 再count,防止撑爆一个reduce(负载均衡优化):

set mapreduce.job.reduce = 5;

-- eg:
select count(distinct id) from bigtable; 
-- 启动了两个任务 第一个任务5个reduce 第二个任务1个reduce 99947条 58秒

--优化:
select count(id) from (select id from bigtable group by id); 
-- 启动了两个任务 第一个任务5个reduce 第二个任务5个reduce 99947条 91秒

8.笛卡尔积避免

join时不要加on条件,或者不要加无用的on条件。

Hive只能使用一个reducer来完成笛卡尔积。

9.行列优先过滤

在select中,只拿需要的列而需要过滤时,优先让数据先进行过滤。

谓词下推: from表——>join——>where——>select

--先关联,再使用where过滤
select o.id from bigtable b join ori o on o.id=b.id where o.id<=10;
--Time taken:34.406 seconds,Fetched:100row(s)

--优化:先子查询后,再关联表
select b.id from bigtable b join (select id from ori where id <= 10) o on b.id=o.id;
--Time taken:30.058 seconds,Fetched:100row(s)

10.通过控制进程数预防数据倾斜

1、map数和reduce数的合理配置

    (1)切片大小设置

set mapreduce.input.fileinputformat.split.maxsize=100; --设置最大切片值

    (2)复杂文件增大切片大小

    (3)设置reducer大小

-- 默认配置
set hive.exec.reducers.bytes.per.reducer=256000000 --设置reducer默认大小

set hive.exec.reducers.max=1009 --设置reducer的最大数量值

-- 手动配置,当手动配置时优先执行手动配置而不走默认配置
set mapreduce.job.reduces = 15;

2、合并小文件

set hive.input.format; -- 默认小文件合并模式,
-- org.apache.hadoop.hive.ql.io.CombineHiveInputFormat

11.并行执行

hive默认将一个sql语句中的mapreduce、抽样、合并、limit等多个阶段并行执行。

set hive.exec.parallel=true -- 并行运行,true表示开启

set hive.exec.parallel.thread.number=8 -- 并行度,根据集群性能

12.严格模式,建议默认

对一些性能损耗大的语法进行禁止:

1、分区表不指定分区字段 eg: select * from emp;

2、笛卡尔积语句 eg:select e.name,d.name from emp e,dept d;

3、order by 不加 limit 限制 eg:select * from emp order by sal;

set hive.mapred.mode=strict -- 严格模式

13.JVM重用

        JVM重用属于hadoop调优,JVM重用可以使得JVM实例在同一个job中重新使用n次,n的值可以在hadoop的mapred-site.xml文件中进行配置。(mapred-site.xml中,通常在10-20左右)

 
    mapreduce.job.jvm.numtasks
    10
    
      How many tasks to run per jvm. If set to -1,there is no limit. 
    
 

        在hive窗口也可以直接进行设置

set mapreduce.job.jvm.numtasks=10 -- hive中可以修改hadoop的配置文件

14.推测执行

为避免部分任务缓慢运行拖慢进度,推测执行(Speculative Execution)机制,根据一定法则推测“拖后腿”的任务,并为这样的任务启动备份任务,选取最先运行完的结果作为输出。

mapred-site.xml

 
    mapreduce.map.speculative
    true
    
      If true,then multiple instances of some map tasks may be executed in parallel.
    
 

 
    mapreduce.reduce.speculative
    true
    
      If true,then multiple instances of some reduce tasks may be executed in parallel.
    
 

在hive中也提供了配置

set hive.mapred.reduce.tasks.speculative.execution=true 
-- Whether speculative execution for reducers should be turned on.

注:输入大且执行时间普遍长的情况下,推测执行会造成很大的浪费

15.压缩

1、hadoop支持Snappy压缩,但需编译

你可能感兴趣的:(hive,hadoop)