`
flyingdutchman
  • 浏览: 358474 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

深入学习《Programing Hive》:Tuning

    博客分类:
  • Hive
阅读更多
        HiveQL是一种声明式语言,最终会被编译为MapReduce job提交到Hadoop执行。大多情况下,用户并不需要知道Hive是如何运作——只关注手头的业务处理问题就行了。虽然Hive引擎会在在HiveQL语句编译过程中最许多的复杂的工作——查询解析、规划、优化和执行等复杂过程,但是用户大部分时间都可以无视这些过程。
        然而,随着Hive的使用,用户会变得越来越有经验,这时候再深入了解和学习Hive理论后的底层实现细节,用户写的HiveQL语句会更高效,特别是在改写HiveQL时做过更多的性能调优之后。
        本节我们会学习一些性能调优的手段。
       
        优化Jion连接
        Streamtable
        在做在对多个表Jion连接操作时,将小表放在Jion的左边,大表放在Jion的右边,在执行这样的Jion连接时小表中的数据会被缓存到内存当中,这样可以有效减少发生内存溢出错误的几率:
             hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1) WHERE c.val >= b.val AND a.val = 'test' AND b.val = 20130520
        

        对于上面的HiveQL示例,会先执行ON条件筛选,再连接,然会才会执行WHERE过滤条件,ON后的筛选条件主要是针对从表,对主表不起作用,因为是外关联,主表数据都会输出,对于主表的筛选条件应该放在where后面,如果觉得主表不需要关联的数据太多,可以使用子查询,先过滤主表中无用数据
              Hive> SELECT a.val,b.val FROM a JION (
                      SELECT c.val FROM c WHERE c.key = 'test'
                  > ) b ON(a.key = b.key1)
                  > WHERE b.val = 20130520;
        

        由于join操作是在where操作之前执行,所以当你在执行join时,where条件并不能起到减少join数据的作用,如:
              hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)
                  >WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'
        
可以改为:
              hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b
                  > ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07')
        

        在JION操作的每一个MapReduce程序中,Hive都会把出现在JION语句中相对靠后的表的数据stream化,相对靠前的变的数据缓存在内存中,这种情况下最好将大表放在JION的右边
(表中数据a < b < c):
              hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
        

        当然您也可以不将大表放在JION的右边,这是就需要指定使用/*+ STREAMTABLE(..) */:
              hive> SELECT /*+ STREAMTABLE(b) */ a.val, b.val, c.val FROM a JOIN b
                  > ON (a.key = b.key1) JOIN c ON (c.key = b.key1)
        

        另外如果所有参与join的表中其参与join的key都相同,则会将所有的join合并到一个mapred程序中。
       

        Mapjion
        Mapjion是是另外一种特殊JION连接操作,它强调在Map端做JION操作:
              hive> SELECT /*+ MAPJION(a,b) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1) WHERE c.val >= b.val AND a.val = 'test' AND b.val = 20130520
        

        默认情况下Hive是不会在MapJION操作的,用户需要使用/* + MAPJION(tablelist) */关键字来告知Hive编译器来做Map端的连接。 MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多。
        Mapjion是一种避免避免数据倾斜的手段,比如对a表和b表做jion连接操作,其中a中只有很少的上千行或百十行数据,而b中却又上千万或上亿行的数据,而且B表中数据倾斜特别严重,这时候制定对a表示用Mapjion,这样就不会由于数据倾斜导致某个reduce上落数据太多而失败。
        不同的JION连接操作是不支持不等于操作的(如a.x < b.y 或者 a.x like b.y等),Hive语法解析会直接抛出错误。Mapjoin还有一个很大的好处是能够进行不等连接的join操作,如果将不等条件写在WHERE中,那么MapReduce过程中会进行笛卡尔积,运行效率特低,若使Mapjoin操作,在Mapper处理过程中就可以完成了不等值的join操作,效率会高很多:
             hive> select /*+ MAPJION(a) */ a.a ,a.b from a join b where a.a>b.a;
       

       Mapjoin 的限制是无法执行全连接(FULL JION)和右外连接(RIGHT OUTER JOIN)。

       并行执行(Parallel Execution)
       Hive引擎会将一个HiveQL查询语句分解成几个执行阶段(stages)(可以通过EXPLAIN HiveQL看出),默认情况下,Hive会一次执行一个阶段(stage),有时候一个包含多个执行阶段(stages)的HiveQL的stages之间并没有前后执行的依赖顺序,这种情况下将这些stages并行执行是一个很好的选择,可以带来更好的性能。
       将hive.exec.parallel参数设置为true就会激活并行执行的功能,如果一个HiveQL作业可以并行的执行其多个stages,这就会提升集群的利用率:
 
             <property>
                 <name>hive.exec.parallel</name>
                 <value>true</value>
                 <description>Whether to execute jobs in parallel</description>
             </property>
       


       本地模式(Local Mode)
       在处理大的数据集时,Hadoop作业可以从hadoop的全扩展可以带来很大的优势,然而有时候要处理的数据集会很小,在这种场景中,对小数据集的查询激活本机模式是一个不错的选择,这可以相当程度上的避免一些不必要的性能开销。可以在$HIVE_HOME/conf/hive.site.xml中将hive.exec.mode.local.auto参数设置为true由Hive对HiveQL作业自动设置执行模式:
             <property>
                 <name>hive.exec.mode.local.auto</name>
                 <value>true</value>
                 <description>
                     Let hive determine whether to run in local mode automatically
                 </description>
             </property>
       


       JVM重用(JVM Reuse)
       JVM重用是Hadoop的一个性能调整的参数,它也会对Hive产生非常大的影响,特别是在很那避免处理大量小文件的场景中,每一个task执行方式景都很短,要知道默认新情况下每处理一个task都要启动一个JVM进程,JVM进程是一个重量级的进程,这就需要大量的资源的开销,这种情况下使用JVM重用可以大量减少这些不必要的JVM的初始化和销毁的开销,大大缩短总的执行时间。
       这个参数可以再$HADOOP_HOME/conf/mapred-site.xml中设置:
             <property>
                 <name>mapred.job.reuse.jvm.num.tasks</name>
                 <value>10</value>
                 <description>
                     How many tasks to run per jvm.if set to -1,there is no limit.
                 </description>
             </property>
       

       JVM重用必须是针对一个MapReduce作业的同一种task任务的,同一个作业的不同类的task是不能重用JVM的。mapred.job.reuse.jvm.num.tasks为-1表明不限制JVM重用的次数。

       推测式执行(Speculative Execution)
       推测式执行时Hadoop的一个重要的功能,其目的是大大加快hadoop作业的整体执行时间。推测式执行的细节这里不再赘述。这个功能需要设置mapred-site.xml中的两个参数来激活这一功能:
             <property>
                 <name>mapred.map.tasks.speculative.execution</name>
                 <value>true</value>
                 <description>If true,the multiple instances of some map tasks 
                   may be executed in parallel.
                 </description>
             </property>
             <property>
                 <name>mapred.reduce.tasks.speculative.execution</name>
                 <value>true</value>
                 <description>If true,the multiple instances of some reduce tasks 
                   may be executed in parallel.
                 </description>
             </property>
       

       Hive提供了一个参数来控制reduce端的并行执行:
             <property>
                 <name>hive.mapred.reduce.tasks.speculative.execution</name>
                 <value>true</value>
                 <description>
                     Whether speculative execution for reducers should be turned on.
                 </description>
             </property>
       


       索引(Indexes)
       索引可以加快GROUP BY查询语句的执行速度。
       Hive从0.80开始,提供了一个Bitmap位图索引,它主要适用于在一个给定的列中只有几个值的场景。详情见HiveQL索引

       严格模式(Strict Mode)
       Hive中的严格模式可以防止用户发出(可以有问题)的查询无意中造成不良的影响。
       将hive.mapred.mode设置成strict可以禁止三种类型的查询:
       1)、在一个分区表上,如果没有在WHERE条件中指明具体的分区,那么这是不允许的,换句话说,不允许在分区表上全表扫描。这种限制的原因是分区表通常会持非常大的数据集并且可能数据增长迅速,对这样的一个大表做全表扫描会消耗大量资源,结果示例如下:
             hive> SELECT DISTINCT(planner_id) FROM fracture_ins WHERE planner_id = 5;
             FAILED: Error in semantic analysis: No Partition Predicate Found For
             Alias "francture_ins" Table "francture_ins"
       

       必要再WHERE过滤条件中具体指明分区才可以执行成功的查询:
             hive> SELECT DISTINCT(planner_id) FROM fracture_ins 
                 > WHERE planner_id = 5 AND hit_date=20121212;
             ... 结果信息 ...
       

       2)、第二种是禁止执行有ORDER BY的排序要求但没有LIMIT语句的HiveQL查询。因为ORDER BY全局查询会导致有一个单一的reducer对所有的查询结果排序,如果对大数据集做排序,这将导致不可预期的执行时间:
             hive> SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id;
             FAILED: Error in semantic analysis: line 1:56 In strict mode,
             limit must be specified if ORDER BY is present planner_id
       

       应该给上面的HiveQL语句加上LIMIT限制:
             hive> SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id LITMIT 1000;
       

       3)、第三种是禁止产生笛卡尔集。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集:
             hive> SELECT * FROM fracture_act JION fracture_ads
                 > WHERE fracture_act.planner_id = fracture_ads.planner_id;
             FAILED: Error semantic analysis: In strict mode,cartesian product is
             not allowed.If you really want to perform the operation, 
             +set hive.mapred.mode=nonstrict+ 
       

       将之改为JION...ON语句:
             hive> SELECT * FROM fracture_act JION fracture_ads
                 > ON(fracture_act.planner_id = fracture_ads.planner_id);
             ... 查询结果 ...
       
分享到:
评论
1 楼 tivan 2013-09-25  
很好。

相关推荐

    HIVE编程指南

    HIVE编程指南中文版,是由programing hive翻译过来

    Programing1:编程的最终评估1

    下面我们将深入探讨这个评估可能涉及的一些关键知识点。 首先,基础编程语言的语法是必不可少的。无论是Python、Java、C++还是其他语言,掌握变量定义、数据类型(如整型、浮点型、字符串、布尔型等)、控制流程...

    leetcode手册JAVA-test-programing-:测试-编程-

    只要它可以帮助正在学习新算法的人,它是否从某个地方复制并不重要。 图形示例也将非常有帮助。 不要忘记包括测试。 不要删除以前的算法实现。 只需使用您自己的实现添加一个新文件。 美化和清理您的代码以便于阅读...

    Hive编程中文版

    Hive编程指南中文版翻译,Hive programing

    hive-programing

    直线-u'jdbc:hive2:// headnodehost:10001 /; transportMode = http'-f demo.hql #this用于将txt文件存储在azure中 直线-u'jdbc:hive2:// headnodehost:10001 /; transportMode = ...

    Programing with MFC Programing with MFC

    《Programming with MFC》是关于Microsoft Foundation Classes (MFC) 的编程指南,MFC 是微软为Windows应用程序开发提供的...通过深入学习MFC,开发者可以更好地理解和控制Windows应用程序的生命周期,提高开发效率。

    c++ programing and c

    c++ programingc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ programing and cc++ ...

    programing-GIS:代码和笔记本

    通过深入研究这个"programing-GIS:代码和笔记本",学习者不仅可以掌握GIS编程的基本技能,还能了解如何将这些技能应用于实际问题,比如城市规划、环境保护、交通分析等领域。这将是一个宝贵的学习资源,帮助开发者将...

    Python-programing:Python代码

    以上只是Python编程中的一些基础知识点,Python的生态庞大,还有更多高级特性和框架,如网络编程、并发处理、网络爬虫、机器学习、深度学习等,都需要进一步深入学习。Python-programing-main这个压缩包可能包含了...

    web-programing:belajar tentang membuat网站sederhana

    在本课程"web-programing: belajar tentang membuat网站sederhana"中,我们将探索构建简单网站的基本步骤,主要关注CSS这一关键技术。首先,我们需要理解网站的构成元素,包括HTML、CSS以及JavaScript,它们共同构成...

    Algorithm-competitive-programing.zip

    "Algorithm-competitive-programming.zip"这个压缩包文件,显然是为了帮助学习者深入理解和掌握算法以及如何在竞争编程中运用它们。让我们一起探讨其中蕴含的知识点。 1. **算法基础**:算法是一系列精确的步骤,...

    牛客的代码leetcode代码区别-common_programing:common_programing

    本项目“牛客的代码leetcode代码区别-common_programing”似乎是为了对比和整理在牛客网上与LeetCode上的编程题目解法。通过对这些代码的分析,我们可以深入理解不同平台上的解题策略、代码风格以及可能存在的差异。...

    visualization-programing:这是个人毕业设计

    在"visualization-programing:这是个人毕业设计"项目中,我们可以推测这是一个使用TypeScript语言实现的可视化编程工具或平台。 TypeScript是JavaScript的一个超集,由微软开发,旨在提供静态类型检查、类和模块等...

    Competitive-Programing:来自各种在线平台的问题解决方案

    竞争性编程问题入门JavaScript 要运行js文件,请取消注释必需的软件包。安装依赖项npm install node filename.js Python python filename.py 不Leetcode 等级朗格公司再来1个简单的JavaScript 2个简单的JavaScript 3...

    The C Programing language

    根据提供的文件信息,实际内容与要求的C编程语言知识点不符,该文件内容为一份小品剧本,因此将基于剧本中的元素进行无关内容的剔除,接下来将围绕...掌握这些基础概念对于学习更高级的语言和技术也是非常有帮助的。

    competive_programing:精进の记录

    “competive_programing-master”作为压缩包子文件的名称,暗示这是一个Git仓库的主分支,通常包含项目的源代码、文档、测试用例等。用户可能可以从中找到关于如何使用Python解决各种算法问题的示例代码,也可能包含...

    Web-Programing:学习基本的网络编程

    在这个主题中,我们将深入探讨网络编程的基本概念,尤其是与HTML相关的知识,因为这是构建网页内容的关键技术。 网络编程的核心是HTTP(超文本传输协议),它是互联网上应用最广泛的数据通信协议。HTTP允许客户端...

Global site tag (gtag.js) - Google Analytics