map join:
map side join 是针对一下场景进行的优化。两个待连接的表中,有一个表非常大,而另一个非常小,以至于小表可以直接存放到内存中。这样,我们可以将小表复制多份,让每一个map task内存中存在一份(比如放在hash table中),然后只扫描大表:对于大表中的每一条记录key/value,在hash table中查找是否具有相同key的记录,入股有,则连接后输出即可。
场景:MapJoin 适用于有一份数据较小的连接情况。
做法:直接将较小的数据加载到内存中,按照连接的关键字建立索引,大份数据作为MapTask的输入数据对 map()方法的每次输入都去内存当中直接去匹配连接。然后把连接结果按 key 输出,这种方法要使用 hadoop中的 DistributedCache 把小份数据分布到各个计算节点,每个 maptask 执行任务的节点都需要加载该数据到内存,并且按连接关键字建立索引。
reduce join
在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源key/value数据对,没条数据打一个标签(tag),比如:tag=0表示来自文件File1,tag=2表示来自文件File2。
在map阶段, 把关键字作为key输出,并在value中标记出数据是来自data1还是data2。因为在shuffle阶段已经自然按key分组,reduce阶段,判断每一个value是来自data1还是data2,在内部分成2组,做集合的乘积。
这种方法有2个问题:
map阶段没有对数据瘦身,shuffle的网络传输和排序性能很低。
reduce端对2个集合做乘积计算,很耗内存,容易导致OOM。