Hive, 大数据

hive-10 企业级调优

执行计划

基本语法:

EXPLAIN [EXTENED | DEPENDENCY | AUTHORIZATION] query

查看sql生成的MR执行计划

Fetch抓取

fetch抓取是指Hive中对某些情况的查询可以不必使用MapReduce计算

set hive.fetch.task.conversion;
  • none 全部都走mr
  • 默认more

本地模式

Hive可以通过本地模式在单台机器上处理所有的任务,对于小数据集,执行时间可以明显缩短

可以设置hive.exec.mode.local.auto为true来让hive在适当的时候自动启动这个优化

set hive.exec.mode.local.auto=true; // 开启本地mr
// 设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式,默认为134217728即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
// 设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10

表的优化

小表大表join(MapJoin)

小表放在join的左边,可以使用mapjoin让小表的维度表先进内存,在map端完成join

新版的hive已经对小表join大表和大表join小表进行了优化

  • 设置自动选择MapJoin
    • set hive,auto,convert.join=true (默认为true)
  • 大表和小表的阈值设置(默认25M以下是小表)
    • set hive,mapjoin.smalltable.filesize=25000000;

大表join大表

  • 空key过滤
    • 非inner join时使用
    • 不需要字段为NULL的
  • 设置reduce个数
set mapreduce.job.reduces=5;
  • 使用分桶表
    • 将大表拆成小表逐个小表join大表
    • a.id=b.id 根据id哈希分桶 相同id放到一样的桶里
    • set hive.optimize.bucketmapjoin=true
    • set hive.optimize.bucketmapjoin.sortedmerge=true
    • set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat

Group By

默认情况下Map阶段同一key数据分发给一个reduce,当一个key数据过大时就会数据倾斜

并不是所有的聚合操作都需要在reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果

  • 是否在map端进行聚合,默认为true
    • set hive.map.aggr=true
  • 在map端进行聚合操作的条目数目
    • set hive.groupby.mapaggr.checkinterval=100000
  • 有数据倾斜的时候进行负载均衡 默认是false
    • set hive.groupby.skwindata=true

Count(Distinct)去重统计

数据量小的时候无所谓,数据量大的时候由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY 再COUNT的方式来替换,但是需要注意group by造成的数据倾斜问题

行列过滤

少用 * 尽可能指定列名

小文件进行合并

  • 在map执行前合并小文件,减少map数
    • set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat

在Map-Reduce的任务结束时合并小文件的设置:

  • 在map-only任务结束时合并小文件,默认true
    • set hive.merge.mapfiles=true
  • 在map-reduce任务结束时合并小文件,默认false
    • set hive.merge.mapredfiles=true
  • 合并文件的大小,默认256M
    • set hive.merge.size.per.task=268435456
  • 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
    • set hive.merge.smallfiles.avgsize=16777216

合理设置reduce数

调整reduce个数方法一

  • 每个reduce处理的数据量默认是256M
    • hive.exec.reducers.bytes.per.reducer=256000000
  • 每个任务最大的reduce数,默认为1009
    • hive.exec.reducers.max=1009
  • 计算reducer数的公式
    • N=min(参数2, 总输入数据量 / 参数1)
    • 参数2 = 1009

调整reduce个数方法二

  • 在hadoop的mapred-default.xml文件中修改
  • 设置每个job的reduce个数
    • set mapreduce.job.reducers=15

reduce个数并不是越多越好

  • 启动资源和时间消耗
  • 有多少个reduce就会产生多少个文件

并行执行

  • 打开任务并行执行
    • set hive.exec.parallel=true
  • 同一个sql允许最大并行度,默认为8
    • set hive.exec.parallel.thread.number=8

严格模式

  • 对于分区表必须填写分区
    • set hive.strict.checks.no.partition.filter=true
  • 使用order by 必须使用limit
    • set hive.strict.checks.orderby.no.limit=true
  • 临时启用笛卡尔积
    • set hive.strict.checks.cartesian.product=true