粘贴一下我在部门中的一次hive优化的分享。

简述

hive构建在hadoop基础上,利用分布式存储,通过mr引擎实现对大数据的计算。MR会频繁地读写磁盘而且MR任务的启动成本很高。对于hive优化显得尤为重要。而优化的核心就是更好地利用hadoop的分布式特性和hive的有点。本篇从IO、参数设置、案例实战来说明如何优化我们的hive。受限于个人能力,如有不足之处,还望指出,一起沟通讨论。

1、IO

  A、通过列裁剪,只读取需要的列[对select * 的做法应进行严格要求,甚至禁止]

  B、 join操作前,应提前处理表,只读取需要的列,并对数据进行梳理。

     原:select A.char1,B.char2

       from A join B

             on A.id=B.id

        where A.disabled=0 and B.disabled=0

    优:select A.char1,B.char2

          from

            (

              select id,char1

        from a

              where a.disabled=0

             ) A

               join

          (

             select id,char2

          from b

              where b.disabled=0

           ) B

              on A.id=B.id

  C、选择合适的存储类型

    建议使用orc存储格式,作为默认设置[支持切片,有压缩,提高查询速度]。创建表时,指定stored as orcfile

  D、走分区[可选]

    减少读取更多的分区文件,极大地有帮助!处理分区时,不可对分区字段进行操作,否则将会导致全表扫描。

2、join

  A、left semi join取代in

     根据测试,对于在大数据量中查询某些取值时,有效提升查询效率。[测试:从erp_fct_order表中,查找若干数据。left semi join 使用了100'+,in耗时300'+]

   B、map join

   当小表与大表进行关联时,通过map join,使左表进入内存,与右表进行关联。这个阶段不涉及reduce。

   通过设置set hive.auto.convert.join=true;[默认]

       set hive.mapjoin.smalltable.filesize=2500000;[25M,通过配置该属性来确定使用该优化的表的大小,如果表的大小小于此值就会被加载进内存中]

3、设置执行参数

reducer数量

  我们执行语句时,总会看到这个:

   Number of reduce tasks determined at compile time: 1

    In order to change the average load for a reducer (in bytes):

     set hive.exec.reducers.bytes.per.reducer=<number>

     In order to limit the maximum number of reducers:

       set hive.exec.reducers.max=<number>

  In order to set a constant number of reducers:

   set mapreduce.job.reduces=<number>

  Starting Job = job_1515122600431_869586, Tracking URL = http://hadoop04:8088/proxy/application_1515122600431_869586/

  上面其实就是,hadoop确定reduce的数量的方式。

   N=min(hive.exec.reducers.max,总数据量大小/hive.exec.reducers.bytes.per.reducer),默认情况下,hive.exec.reducers.max=999,hive.exec.reducers.bytes.per.reducer=1G;

  我们也可以强制指定reduce数量,mapreduce.job.reduces=N。

  需要注意的是,有的reduce为0,有的只为1。

  为0,即为该任务只有map,没有reduce。

      为1,即为全局,如order by、count、笛卡尔积。

mapper的数量

  map端处理文件时,将对文件进行拆分成若干个task数。而如何拆分,这本身和文件的存储类型相关。hive系统默认的类型为org.apache.hadoop.hive.ql.io.CombineHiveInputFormat[set hive.input.format;],当我们不指定存储类型时,hive将根据文件本身设置对应的存储类型。如:org.apache.hadoop.mapred.TextInputFormat。

  继承了FileInputFormat的切分算法:splitSize = max{split.size,min{goalSize,blockSize}}

  若格式为:HiveInputFormat

  split.size:mapred.min.split.size,默认为1。切片最小大小,没有什么能比这个更小的了。

    goalSize:目标大小,为用户设置的map task数与实际大小决定。goalSize=总大小/设置的mapred.map.tasks的大小[默认为2]

  blockSize:块大小[set dfs.block.size],当前我们系统的块为:128M

  所以,当我们没有设置最小的切片大小时,切片的大小,取决于文件大小、设置的mapred.map.tasks数、块大小.

   例如:一个文件如果是300M,则切片大小为:splitSize=max{1,min{300/2,128}}=128M,则3个map对应的文件大小为:128,128,46

   若格式为:TextInputFormat:

   split.size:mapred.max.split.size,[当前系统为256M],则splitSize为max{256,min{300/2,128}}=256,则只有一个map.

小结

  mapper的数量合适,单个mapper处理的数据量合适;拆分大小尽量与block数据块相同,避免一个拆分块大小有多个 hdfs 块,且位于不同数据节点,从而降低网络 IO。如果想减少mapper的数据量,一般只要将mapred.max.split.size设置的更大就可以了。

合并小文件

  hive基于NameNode进行调度管理和任务分发,NameNode本身是有瓶颈的,有固定的大小。在hadoop任务中,NameNode加载必要的信息,其中包括各个文件的元数据(位置、大小、块信息等)。一般情况下,当文件数达到1000W时,所占用的NameNode内存达到3G,将带来性能下降。Hadoop本身对大文件具有很高的处理能力,但在mr任务过程中,map任务和reduce任务都会带来小文件的问题。当小文件作为输入,由map来进行处理时,启用map带来的时间比处理更耗时。此外,reduce数量多的话,产生的小文件也会增多。

  输入时合并

  set mapred.max.split.size=256000000;-- 每个Map最大输入大小,决定合并后的文件数

  set mapred.min.split.size.per.node=100000000; -- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并 [当前设置为:1,默认设置。设置该参数,一定要设置下方的rack参数,否则报错。]

  set mapred.min.split.size.per.rack=100000000; -- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并 [当前设置为:1,默认设置]

  set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 执行Map前进行小文件合并[经过测试,设置上面的参数就能够让小文件进行合并了。]

  输出时合并

  set hive.merge.mapfiles=true; -- 在map-only job后合并文件,默认true

  set hive.merge.mapredfiles=true; -- 在map-reduce job后合并文件,默认false

  set hive.merge.size.per.task=256000000; -- 合并后每个文件的大小,默认256000000

  set hive.merge.smallfiles.avgsize=16000000; -- 平均文件大小,当结果文件小于该值时,将进行合并

数据倾斜

原因:当我们进行join操作时,会在map端根据key的hash值,shuffle到某一个reduce上去,在reduce端做join连接操作,内存中缓存join左边的表,遍历右边的表,一次做join操作。所以在做join操作时候,将数据量多的表放在join的右边。当数据量比较大,并且key分布不均匀,大量的key都shuffle到一个reduce上了,就出现了数据的倾斜。

场景

key为空:当join的key存在空值时,这些值会被hash到同一个reduce中,导致数据倾斜。遇到这样的情况,建议区分空和非空

count(distinct):数据聚合类的操作sum、count,因为已经在map端做了聚合操作了,到reduce端的数据相对少一些[主要设置参数为:1.set hive.map.aggr=true;默认值,是否在map端进行聚合;2.set hive.groupby.mapaggr.checkinterval = 100000;默认值,在 Map 端进行聚合操作的条目数目],不会出现这个问题。当distinct时,会对group by后的字段和distinct的字段进行hash,如果存在大量重复值,则会导致数据倾斜。

遇到倾斜时set hive.groupby.skewindata = true;[负载均衡,默认为false。查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作]

常用参数设置及说明

--类型:输入时合并小文件

  set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; ----可在map端进行合并,减少小文件

  set mapred.max.split.size=256000000;  ----设置一个合理的数值,最大的切片数据。影响map的个数

  set mapred.min.split.size.per.node=134217728;  ----一个节点上的最小切片大小。设置为block大小

  set mapred.min.split.size.per.rack=256000000;  ----一个交换机上的最小切片大小

--类型:资源占用量

  set mapreduce.map.memory.mb=5120;

  set mapreduce.reduce.memory.mb=5120;

--类型:设置最大值

  set mapreduce.job.reduces=80;  ----用来对reduer数量进行控制,但设置的过大,不设置效果更好

  set hive.exec.reducers.max=80; ----最大的reduce数

--类型:mapjoin

  set hive.auto.convert.join=true;

  set hive.mapjoin.smalltable.filesize=2500000;

--类型:输出时合并

  set hive.merge.mapfiles=true; -- 在map-only job后合并文件,默认true

  set hive.merge.mapredfiles=true; -- 在map-reduce job后合并文件,默认false

  set hive.merge.size.per.task=256000000; -- 合并后每个文件的大小,默认256000000

  set hive.merge.smallfiles.avgsize=16000000; -- 平均文件大小,当结果文件小于该值时,将进行合并

--类型:并发及并发数

  set hive.exec.parallel=true;

  set hive.exec.parallel.thread.number=16;

补充

在写sql的过程中,有时候会用到排序。但是在hive中用order by排序,将带来一个问题。只有一个reduce。往往带来性能的较差。Hive为查询提供了其他排序方式。

  Order by:全局,一个reduce【不建议】

  Distribute by :map的输出排序,排序后,将对应的key通过hash放入到reduce中

  Sort by:局部排序,在每个reduce中实现排序。当reduce数只有一个时,sort by和order by结果没有什么差异【建议】

Cluster by:分桶中用到,用来指定分桶的字段。cluster by  key = distribute by key sort by key desc  ,是一个简写。cluster by只能降序排序。

原创博客,转载请注明出处!欢迎邮件沟通:shj8319@sina.com

hive优化分享的更多相关文章

  1. Hive 12、Hive优化

    要点:优化时,把hive sql当做map reduce程序来读,会有意想不到的惊喜. 理解hadoop的核心能力,是hive优化的根本. 长期观察hadoop处理数据的过程,有几个显著的特征: 1. ...

  2. hive优化之——控制hive任务中的map数和reduce数

    一.    控制hive任务中的map数: 1.    通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文 ...

  3. Hive优化案例

    1.Hadoop计算框架的特点 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业效率相对比较低,比如即使有几百万的表,如果多次关联多次汇总,产生十几个jobs,耗时很长.原因是map re ...

  4. 一起学Hive——总结常用的Hive优化技巧

    今天总结本人在使用Hive过程中的一些优化技巧,希望给大家带来帮助.Hive优化最体现程序员的技术能力,面试官在面试时最喜欢问的就是Hive的优化技巧. 技巧1.控制reducer数量 下面的内容是我 ...

  5. 大数据技术之_08_Hive学习_04_压缩和存储(Hive高级)+ 企业级调优(Hive优化)

    第8章 压缩和存储(Hive高级)8.1 Hadoop源码编译支持Snappy压缩8.1.1 资源准备8.1.2 jar包安装8.1.3 编译源码8.2 Hadoop压缩配置8.2.1 MR支持的压缩 ...

  6. 大数据开发实战:Hive优化实战3-大表join大表优化

    5.大表join大表优化 如果Hive优化实战2中mapjoin中小表dim_seller很大呢?比如超过了1GB大小?这种就是大表join大表的问题.首先引入一个具体的问题场景,然后基于此介绍各自优 ...

  7. 大数据开发实战:Hive优化实战1-数据倾斜及join无关的优化

    Hive SQL的各种优化方法基本 都和数据倾斜密切相关. Hive的优化分为join相关的优化和join无关的优化,从项目的实际来说,join相关的优化占了Hive优化的大部分内容,而join相关的 ...

  8. Hadoop生态圈-hive优化手段-作业和查询优化

    Hadoop生态圈-hive优化手段-作业和查询优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  9. 【转】Hive优化总结

    优化时,把hive sql当做map reduce程序来读,会有意想不到的惊喜. 理解Hadoop的核心能力,是hive优化的根本.这是这一年来,项目组所有成员宝贵的经验总结.   长期观察hadoo ...

随机推荐

  1. web开发如何使用高德地图API(一)浏览器定位

    说两句: 以下内容除了我自己写的部分,其他部分在高德开放平台都有(可点击外链访问). 我所整理的内容以实际项目为基础希望更有针对性的,更精简. 点击直奔主题. 准备工作: 首先,注册开发者账号,成为高 ...

  2. Cloudera 5.8.3 SolrCloud+HDFS的索引数据备份和恢复。(需重启solr进程。)

    一.备份基于HDFS的solrCloud集合数据 1.确认要备份的solr文件夹. /solr/history_customer_collection_test 2.开启HDFS快照功能. hdfs ...

  3. 零基础学python-2.16 列表解析

    这一节聊聊强大的列表解析 主要就是在一行里面赋值给列表 以下我们举两个样例: 上面的样例我们引入了range函数,他主要作用是在一定范围里面取整数值 我来解释一下中括号中面的那一句:x**2 for ...

  4. CNN中的局部连接(Sparse Connectivity)和权值共享

    局部连接与权值共享 下图是一个很经典的图示,左边是全连接,右边是局部连接. 对于一个1000 × 1000的输入图像而言,如果下一个隐藏层的神经元数目为10^6个,采用全连接则有1000 × 1000 ...

  5. Node.js:NPM 使用介绍

    ylbtech-Node.js:NPM 使用介绍 1.返回顶部 1. NPM 使用介绍 NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: ...

  6. thinkphp 内存查询表 防止多次查库

    //从内存查询 表 以防止多次查库 private static function selectTable($tableName,array $where,$getFirst=false){ $res ...

  7. 关于chm提示 已取消到该网页的导航的解决方法

    下载了一个chm文件,打开提示“已取消到该网页的导航”,以前以为是文件有问题,下载其他的也是出现这种情况,于是网上搜了下,解决方法如下: 方法 1 1. 双击此 .chm 文件. 2. 在“打开文件安 ...

  8. Java单例模式解析(收藏)

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下. 所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在.就 ...

  9. JavaScript中的工厂方法、构造函数与class

    JavaScript中的工厂方法.构造函数与class 本文转载自:众成翻译 译者:谢于中 链接:http://www.zcfy.cc/article/1129 原文:https://medium.c ...

  10. JavaScript实现网页换肤

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...