hive优化

注:下文中输入数据大小指的是desc formatted 表名返回的rawDataSize,文件个数为返回的numFiles

1. 不跑MR程序进行数据抽取

配置项:hive.fetch.task.conversion

取值 描述
more 默认值,SELECT, FILTER, LIMIT only (including TABLESAMPLE, virtual columns, UDF, 表达式)
minimal SELECT *, FILTER on partition columns (WHERE and HAVING clauses), LIMIT only
none 禁用该功能,执行MR

2. 小任务本地执行

配置项:hive.exec.mode.local.auto,默认为false,开启后,MR转本地执行,还需满足下表的配置项

配置 默认值 描述
hive.exec.mode.local.auto.inputbytes.max 134217728,即128MB 开启MR转本地执行时,输入数据大小的最大值
hive.exec.mode.local.auto.tasks.max 4 开启MR转本地执行时,map任务数最大值
hive.exec.mode.local.auto.input.files.max 4 开启MR转本地执行时,输入文件个数的最大值

3. map join

配置项:hive.auto.convert.join,默认为true,需满足下表的配置项

配置 默认值 描述
hive.mapjoin.smalltable.filesize 25000000,即25MB 当rawDataSize小于该值时,可以使用mapjoin
hive.auto.convert.join.noconditionaltask true 多个map join转成一个map join
hive.auto.convert.join.noconditionaltask.size 10000000,即10MB 多个join的小表的大小总和不超过该值

map join过程

  • Local work:
    • 将表中的数据读到本地
    • 构建hash表
    • 将hash表序列化到本地
    • 上传本地文件到hdfs
    • 将文件添加到分布式缓存
  • Map task
    • 在内存中序列化生成hash表
    • 对大表中的数据一条条进行匹配
      -- 合并匹配的数据并输出

4. bucket map join

要求:关联字段是分桶字段,且两张表的分桶字段类型相同,桶的个数成倍数关系。

配置 默认值 描述
hive.auto.convert.sortmerge.join false 是否将桶的join自动转成map join
hive.optimize.bucketmapjoin false 是否开启bucket map join
hive.optimize.bucketmapjoin.sortedmerge false 是否将Sort-Merge-Bucket (SMB) joins 转成SMB map joins
hive.auto.convert.sortmerge.join.bigtable.selection.policy org.apache.hadoop.hive.ql.optimizer.AvgPartitionSizeBasedBigTableSelectorForAutoSMJ 大表选择策略,共3种

5. groupby 相关优化

  • 配置:hive.groupby.skewindata,默认为false
    • 为true,会增加一个MR,第一个MR用来将key随机化,然后聚合,第二个MR使用真正的key聚合,由于第一个MR已经聚合了一部分数据,这样避免数据倾斜
  • hive.map.aggr
    • 默认为true,开启map端聚合
  • hive.groupby.mapaggr.checkinterval
    • 默认为100000条,map端聚合使用hash表来聚合,当读取的数据达到了该值,则会检查一下是否需要溢写
  • hive.map.aggr.hash.percentmemory
    • 默认为0.5,当map端聚合使用hash表的内存超过了堆内存的该比例时,则溢写到磁盘

6. count(distinct)

当id数据倾斜时或表数据量较大时,将count(distinct id)改成

select count(1) from (select id from t group by id) t

7. 小表join大表

这里的小表不是指的map join类型的小表,而是关联key在这个表中没有倾斜,同理大表指的是关联key存在倾斜。遇到这样的表进行join,需要把小表放在左边。原因与hive表的join实现有关:

  1. map端,输出的key为关联key与tag的组合键,tag表示数据来源,左边的表的tag小,分组按原始的key,排序使用组合键;输出的value也是tag与原始value的组合
  2. reduce端,经过排序后,对相同的key,左边表的数据会先获取到,放入到内存中,右边的表是读一条,关联内存中的左表数据,输出
  3. 假设大表放到左边,由于它的记录被放入到了内存,数据倾斜可能导致OOM

对于这样的情况,还有一种是使用skewed table并使用list bucketing,笔者的上篇文章hive总结已经有讲,注意要配置hive.optimize.skewjoin.compiletime=true,这个选项的意思是在编译生成执行计划时,会使用skewed table的元数据来对倾斜的key做优化。

还有一个配置hive.optimize.skewjoin,它会在reduce端统计数据倾斜的key,当相同key超过hive.skewjoin.key(默认100000),则认为该key倾斜,此时hive会启用另一个map join来处理倾斜的key

8. 大表join大表

大表指的是关联key存在倾斜(没有无效KEY)。对于这种情况,有一种解决方式是使用skewed table并使用list bucketing或者启用hive.optimize.skewjoin,由于它们的处理方式都是最后进行map join,需要将一张表的部分数据放入到内存,假设极端情况下,放入到内存的表的相同key也倾斜,导致放入到内存会引起OOM,这时有一种思路是将这张表倾斜的数据切分为若干块,将这一块加载到内存与另一张表中倾斜的数据进行map join,这样并行处理分成的若干块。

9. 其它

  • 并行执行
  • 推测执行
  • 对无效KEY进行过滤或加上随机值
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Hive优化 今天的主要内容——Hive优化 Fetch抓取Hive 中对某些情况的查询可以不必使用 MapRed...
    须臾之北阅读 1,285评论 0 3
  • 小文件问题的影响1.从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,...
    JayWolf阅读 1,897评论 0 0
  • 本节所讲优化策略适用于任何场景 1.核心思想 把Hive SQL 当做Mapreduce程序去优化以下SQL不会转...
    文茶君阅读 606评论 0 0
  • Fetch 抓取 Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELE...
    ZFH__ZJ阅读 1,954评论 0 3
  • Hive的优化策略大致分为:配置优化(hive-site.xml和hive-cli执行前配置)、表优化、hive数...
    李小李的路阅读 6,611评论 0 10

友情链接更多精彩内容