Hive的mapjoin原理与参数说明

一、 Map Join原理

  1. Map Join介绍
    MapJoin顾名思义,就是在Map阶段进行表之间的连接,map阶段直接拿另外一个表的数据和内存中表数据做匹配。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。通常用于一个很小的表和一个大表进行join的场景。

  2. MapJoin的原理及过程
    在这里插入图片描述
    执行过程如上图:

  1. 首先是在本地客户端生成的Task A,是一个MapReduce Local Task,负责把小表数据从HDFS读取到内存哈希表。读取后,它会将内存中的哈希表序列化为磁盘上的文件,并将哈希表文件压缩为tar文件
  2. 接下来是Task B,该任务是一个没有Reduce的MapReduce任务,启动的时候,上一步骤的tar文件会被放到Hadoop分布式缓存中,Hadoop分布式缓存将把tar文件填充到每个Mapper的本地磁盘并解压缩该文件。然后mapper可以将哈希表文件反序列化回内存,并像以前一样执行join工作,也就是根据大表中的每一条记录去和DistributeCache中小表对应的HashTable关联,并直接输出结果。

        关于自动优化:对于MapJoin,查询处理器应该知道大表是哪个输入表。在执行阶段,其他输入表将被识别为小表,这些表需要保存在内存中。但是,一般来说,查询处理器在编译期间不知道输入文件的大小(即使有统计数据),因为某些表可能是由子查询生成的中间表。所以查询处理器只能在执行期间计算出输入文件的大小。

二、 版本区别

        之前的Hive版本,需要使用hint提示 /*+ mapjoin(table) */才会执行MapJoin,否则执行Common Join,自0.11后,默认自动会转换Map Join,由参数hive.auto.convert.join来控制,默认为true。issue链接:
https://issues.apache.org/jira/browse/HIVE-3297
但是0.11之前包括0.11的版本BUG比较多,建议使用0.12后的版本

三、 参数说明

         hive.auto.convert.join = true
        自动将common join转换为map join解决了这个问题
        hive.mapjoin.smalltable.filesize=30000000
        如果原始小表的总大小大于该值,则任务将选择原始的common join运行。
        hive.mapjoin.localtask.max.memory.usage = 0.999;
        本地任务的内存使用率阈值。若是客户端内存足够的时候,建议调大
        hive.auto.convert.join.noconditionaltask
        是否将多个mapjoin合并为一个。合并的好处在于每个mapjoin都会有一个mapper,对数据进行多次的读写,合并mapjoin以后只会有一个mapper,所以只需要读取一次会加快速度。
        hive.auto.convert.join.noconditionaltask.size
        多个mapjoin转换为1个时,所有小表的文件大小总和的最大值。根据内存大小调整
        hive.mapjoin.followby.gby.localtask.max.memory.usage
        如果mapjoin后面紧跟着一个group by任务,这种情况下 本地任务的最大内存使用率,默认是0.55。一般不做改动
        hive.mapjoin.check.memory.rows
        localtask每处理完多少行,就执行内存检查,默认为100000,当localtask的内存使用超过阀值,任务会直接失败。一般不做改动

四、 参考链接

        https://cwiki.apache.org/confluence/display/Hive/MapJoinOptimization
        https://issues.apache.org/jira/browse/HIVE-1642
        https://issues.apache.org/jira/browse/HIVE-1641

猜你喜欢

转载自blog.csdn.net/xiaozhaoshigedasb/article/details/105245698