• hive mapjoin


    笼统的说,Hive中的Join可分为Common Join(Reduce阶段完成join)和Map Join(Map阶段完成join)

    一、Hive Common Join

    如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join.
    整个过程包含Map、Shuffle、Reduce阶段。

    • Map阶段

    读取源表的数据,Map输出时候以Join on条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;
    Map输出的value为join之后所关心的(select或者where中需要用到的)列;同时在value中还会包含表的Tag信息,用于标明此value对应哪个表;
    按照key进行排序

    • Shuffle阶段

    根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中

    • Reduce阶段
      根据key的值完成join操作,期间通过Tag来识别不同表中的数据。

     

     

    二、Hive Map Join

    1,什么是MapJoin?

    MapJoin顾名思义,就是在Map阶段进行表之间的连接。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。


    2,MapJoin的原理:

    通常情况下,要连接的各个表里面的数据会分布在不同的Map中进行处理。即同一个Key对应的Value可能存在不同的Map中。这样就必须等到Reduce中去连接

    要使MapJoin能够顺利进行,那就必须满足这样的条件:除了一份表的数据分布在不同的Map中外,其他连接的表的数据必须在每个Map中有完整的拷贝。


    3,MapJoin适用的场景:


    通过上面分析你会发现,并不是所有的场景都适合用MapJoin. 它通常会用在如下的一些情景:在二个要连接的表中,有一个很大,有一个很小,这个小表可以存放在内存中而不影响性能。

    这样我们就把小表文件复制到每一个Map任务的本地,再让Map把文件读到内存中待用。

    4,MapJoin的实现方法

         1)在Map-Reduce的驱动程序中使用静态方法DistributedCache.addCacheFile()增加要拷贝的小表文件,。JobTracker在作业启动之前会获取这个URI列表,并将相应的文件拷贝到各个TaskTracker的本地磁盘上。
     
         2)在Map类的setup方法中使用DistributedCache.getLocalCacheFiles()方法获取文件目录,并使用标准的文件读写API读取相应的文件。
     

    5,Hive内置提供的优化机制之一就包括MapJoin。

    在Hive v0.7之前,需要使用hint提示 /*+ mapjoin(table) */才会执行MapJoin  。Hive v0.7之后的版本已经不需要给出MapJoin的指示就进行优化。它是通过如下配置参数来控制的:
     
    hive> set hive.auto.convert.join=true;
      
    Hive还提供另外一个参数--表文件的大小作为开启和关闭MapJoin的阈值。
     
    hive.mapjoin.smalltable.filesize=25000000 即25M

     

     三、mapjoin 解决数据倾斜

    今天遇到一个hive的问题,如下hive sql:

    select f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802)  

    该语句中B表有30亿行记录,A表只有100行记录,而且B表中数据倾斜特别严重,有一个key上有15亿行记录,在运行过程中特别的慢,而且在reduece的过程中遇有内存不够而报错。

    为了解决用户的这个问题,考虑使用mapjoin,mapjoin的原理:

    MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多

    这样就不会由于数据倾斜导致某个reduce上落数据太多而失败。于是原来的sql可以通过使用hint的方式指定join时使用mapjoin。

    select /*+ mapjoin(A)*/ f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802) 

    再运行发现执行的效率比以前的写法高了好多。

    mapjoin还有一个很大的好处是能够进行不等连接的join操作,如果将不等条件写在where中,那么mapreduce过程中会进行笛卡尔积,运行效率特别低,

    如果使用mapjoin操作,在map的过程中就完成了不等值的join操作,效率会高很多。

    例子:

    select A.a ,A.b from A join B where A.a>B.a

    简单总结一下,mapjoin的使用场景:

    1. 关联操作中有一张表非常小

    2.不等值的链接操作

  • 相关阅读:
    Ubuntu 14.04 LTS 安装 NVIDIA 显卡驱动后的屏幕亮度调节问题
    算法算法算法
    Java transient关键字
    使用git和github管理自己的项目---基础操作学习[转]
    Linux 查看系统硬件信息[转]
    实现Servlet容器一
    nginx入门三
    nginx入门二
    nginx入门一
    centos7入门
  • 原文地址:https://www.cnblogs.com/qiuhong10/p/7698277.html
Copyright © 2020-2023  润新知