Hive调优思路——知识总结

本文详细探讨了如何通过选择合适的存储格式(TextFile, SequenceFiles, RCFile, ORCFile, Parquet)和压缩方式(Gzip, NONE, RECORD, BLOCK)来优化Hive的数据处理性能。此外,还介绍了如何通过创建分区表、桶表、拆分表,调整Hive参数,优化SQL查询以及处理数据倾斜来进一步提升效率。
摘要由CSDN通过智能技术生成

Hive调优:

  1. 对分析的数据选择合适的「存储格式」与「压缩方式」能提高hive的分析效率

    • 数据的压缩格式:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nak9Rpb5-1628996895029)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/669b62e5-c166-452e-acce-75d8aef420ac/Untitled.png)]

      • 选择压缩算法的时候需要考虑到是否可以分割,如果不支持分割(切片的时候需要确定一条数据的完整性),则一个map需要执行完一个文件,如果文件很大,则效率很低。一般情况下hdfs一个块(128M)就是一个map的输入切片,而block是按物理切割的,可能一条数据会被切到两个块中去
    • 数据的存储格式:

      1. TextFile(行存储、Gzip压缩)
        • Hive数据表的默认格式,存储方式:行存储。 可以使用Gzip压缩算法,但压缩后的文件不支持split 在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。
      2. Sequence Files(行存储、NONE/RECORD/BLOCK压缩)
        • Hadoop中有些原生压缩文件的缺点之一就是不支持分割。支持分割的文件可以并行的有多个mapper程序处理大数据文件,大多数文件不支持可分割是因为这些文件只能从头开始读。Sequence File是可分割的文件格式,支持Hadoop的block级压缩。 Hadoop API提供的一种二进制文件,以key-value的形式序列化到文件中。存储方式:行存储。 sequencefile支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,RECORD是默认选项,通常BLOCK会带来较RECORD更好的压缩性能。 优势是文件和hadoop api中的MapFile是相互兼容的
      3. RCFile(行列结合存储)
        • 存储方式:数据按行分块,每块按列存储。结合了行存储和列存储的优点
        • 首先,RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低 其次,像列存储一样,RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取 数据追加:RCFile不支持任意方式的数据写操作,仅提供一种追加接口,这是因为底层的 HDFS当前仅仅支持数据追加写文件尾部。 行组大小:行组变大有助于提高数据压缩的效率,但是可能会损害数据的读取性能,因为这样增加了 Lazy 解压性能的消耗。而且行组变大会占用更多的内存,这会影响并发执行的其他MR作业
      4. ORCFile(行列结合存储)
        • 存储方式:数据按行分块,每块按照列存储
        • 压缩快,快速列存取。效率比rcfile高,是rcfile的改良版本
      5. Parquet(行存储)
        • Parquet也是一种行式存储,同时具有很好的压缩性能;同时可以减少大量的表扫描和反序列化的时间
  2. 创建分区表、桶表、拆分表

  3. Hive参数优化

    • 不执行MR:

      • fetch task 为执行hive时,不用执行MapReduce,如select * from emp
      Hive.fetch.task.conversion 默认为minimal
       
      修改配置文件hive-site.xml
      <property>
        <name>hive.fetch.task.conversion</name>
        <value>more</value>
        <description>
          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 incurrs RS), 
          lateral views and joins.
          1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
          2. more    : SELECT, FILTER, LIMIT only (+TABLESAMPLE, virtual columns)
        </description>
      </property> 
       
       
      或者当前session修改
      hive> set hive.fetch.task.conversion=more;
      执行SELECT id, money FROM m limit 10; 不走mr
      
    • 并行执行:

      • 当一个sql中有多个job时候,且这多个job之间没有依赖,则可以让顺序执行变为并行执行(一般为用到union all )
      // 开启任务并行执行
      set hive.exec.parallel=true;
      // 同一个sql允许并行任务的最大线程数 
      set hive.exec.parallel.thread.number=8;
      
    • JVM 重用:

      • JVM重用对hive的性能具有非常大的 影响,特别是对于很难避免小文件的场景或者task特别多的场景,这类场景大多数执行时间都很短。jvm的启动过程可能会造成相当大的开销,尤其是执行的job包含有成千上万个task任务的情况。
      • JVM的一个缺点是,开启JVM重用将会一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡“的job中有几个 reduce task 执行的时间要比其他reduce task消耗的时间多得多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放
      set mapred.job.reuse.jvm.num.tasks=10;
      
    • 设置reduce的数目:

      • reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:

        • hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量)
        • hive.exec.reducers.max(每个任务最大的reduce数)
      • 调整reduce个数的方法:

        • 调整hive.exec.reducers.bytes.per.reducer参数的值
        set hive.exec.reducers.bytes.per.reducer=500000000;500M)
        
        • 调整mapred.reduce.tasks参数的值
        set mapred.reduce.tasks = number
        
      • reduce个数并不是越多越好; 同map一样,启动和初始化reduce也会消耗时间和资源; 另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题

  4. 优化SQL查询

    • where条件优化:

      • 优化前(关系数据库不用考虑会自动优化):
      select m.cid,[u.id](http://u.id/) from order m join customer u on( m.cid =[u.id](http://u.id/) )where m.dt='20180808'
      
      • 优化后(where条件在map端执行而不是在reduce端执行):
      select m.cid,[u.id](http://u.id/) from (select * from order where dt='20180818') m join customer u on( m.cid =[u.id](http://u.id/));
      
    • union优化:

      • 尽量不要使用union (union 去掉重复的记录)而是使用 union all 然后在用group by 去重
    • count distinct优化:

      • 不要使用count (distinct cloumn) ,使用子查询
      select count(1) from (select id from tablename group by id) tmp;
      
    • 用 in 来代替 join:

      • 如果需要根据一个表的字段来约束另为一个表,尽量用in来代替join
      select id,name from tb1  a join tb2 b on([a.id](http://a.id/) = [b.id](http://b.id/));
      select id,name from tb1 where id in(select id from tb2); in 要比join
    • 消灭子查询内的 group by 、 COUNT(DISTINCT),MAX,MIN。 可以减少job的数量

    • join 优化:

      • 在小表和大表进行join时,将小表放在前边,效率会高,hive会将小表进行缓存
  5. 数据倾斜:

    • 表现:任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大

    • 原因:某个reduce的数据输入量远远大于其他reduce数据的输入量

      1. key分布不均匀
      2. 业务数据本身的特性
      3. 建表时考虑不周
      4. 某些SQL语句本身就有数据倾斜

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-upl4b9WJ-1628996895032)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/41237eec-b21f-463e-9d0c-314098583d3b/Untitled.png)]

    • 解决方案:

      • 参数调节:
      set hive.map.aggr=true //map端部分聚合,相当于combiner
      set hive.groupby.skewindata=true
      
      • 第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的
      • 第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作
    • 熟悉数据分布,优化SQL逻辑,找到数据倾斜的原因

  6. 合并小文件

    • 小文件的产生有三个地方,map输入,map输出,reduce输出,小文件过多也会影响hive的分析效率:

      • 设置map输入的小文件合并:
      set mapred.max.split.size=256000000;
      //一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
      set mapred.min.split.size.per.node=100000000;
      //一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
      set mapred.min.split.size.per.rack=100000000;
      //执行Map前进行小文件合并
      set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
      
      • 设置map输出和reduce输出进行合并的相关参数:
      //设置map端输出进行合并,默认为true
      set hive.merge.mapfiles = true
      //设置reduce端输出进行合并,默认为false
      set hive.merge.mapredfiles = true
      //设置合并文件的大小
      set hive.merge.size.per.task = 256*1000*1000
      //当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
      set hive.merge.smallfiles.avgsize=16000000
      
  7. 查看HQL执行计划:

    • Explain SQL
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值