hive mapjoin 原理

1、什么是MapJoin?

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

2、MapJoin的原理:


即在map 端进行join,其原理是broadcast join,即把小表作为一个完整的驱动表来进行join操作。通常情况下,要连接的各个表里面的数据会分布在不同的Map中进行处理。即同一个Key对应的Value可能存在不同的Map中。这样就必须等到 Reduce中去连接。要使MapJoin能够顺利进行,那就必须满足这样的条件:除了一份表的数据分布在不同的Map中外,其他连接的表的数据必须在每 个Map中有完整的拷贝。MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多。


3、MapJoin适用的场景:


mapjoin的适用场景如关联操作中有一张表非常小,.不等值的链接操作。通过上面分析你会发现,并不是所有的场景都适合用MapJoin. 它通常会用在如下的一些情景:在二个要连接的表中,有一个很大,有一个很小,这个小表可以存放在内存中而不影响性能。这样我们就把小表文件复制到每一个Map任务的本地,再让Map把文件读到内存中待用

4、执行流程

hive mapjoin 原理

执行流程如下: 

  • 如图中的流程,首先是Task A,它是一个Local Task(在客户端本地执行的Task),负责扫描小表b的数据,将其转换成一个HashTable的数据结构,并写入本地的文件中,之后将该文件加载到DistributeCache,该HashTable的数据结构可以抽象为: 
    |key| value| 
    | 1 | 26 | 
    | 2 | 34 |

hive mapjoin 原理
图中红框圈出了执行Local Task的信息。 
- 接下来是Task B,该任务是一个没有Reduce的MR,启动MapTasks扫描大表a,在Map阶段,根据a的每一条记录去和DistributeCache中b表对应的HashTable关联,并直接输出结果。 

5、相关参数

1、小表自动选择Mapjoin

set hive.auto.convert.join=true;

默认值:false。该参数为true时,Hive自动对左边的表统计量,若是小表就加入内存,即对小表使用Map join

 

2、小表阀值

set hive.mapjoin.smalltable.filesize=25000000;

默认值:25M

hive.smalltable.filesize (replaced by hive.mapjoin.smalltable.filesize in Hive 0.8.1)

 

3、map join做group by操作时,可使用多大的内存来存储数据。若数据太大则不会保存在内存里

set hive.mapjoin.followby.gby.localtask.max.memory.usage;

默认值:0.55

 

4、本地任务可以使用内存的百分比

set hive.mapjoin.localtask.max.memory.usage;

默认值:0.90