您的位置:首页 > 其它

MapReduce模型中常用join方法小结

2012-04-21 21:55 375 查看
这篇文章是在阅读《A Comparison of Join Algorithms for Log Processing in MapReduce》后对该文的一个小结。该文章详细介绍几种在mapreduce模型下的join算法,并且对他们的性能作出系统的评测。目前像pig,hive等上层应用在进行join计算时也是利用该文中提出的算法或者算法变种。

需求:
假设有两个数据源L,R,目前需要对这两个数据源中的记录根据某一共同属性k做equi-join操作,即将所有的L.k==R.k的记录连接起来。

1、 Repartition Join(再分配连接)

该算法是目前最为通用的一种join算法。该算法的核心思想是在shuffle阶段将k值相同的记录分配到同一个reduce任务中,并且在reduce中作出连接操作。该算法已经在org.apache.hadoop.contrib.utils.join中实现。

标准版

首先,在map阶段,每个map对一个L的分片或者R的分片进行处理,并且将k的值作为中间记录的键,将记录的其他部分以及记录的来源(即是来自于L还是来自于R)做为中间记录的值。这样,所有k的值相同的记录都将被分配到同一个reduce函数中处理。在reduce函数中,我们只需要将所有的记录取出,并且根据值来判断该记录是来自于L还是R,然后将属于L的记录和属于R的记录进行连接操作即可。

这种方法有一个缺点,需要在reduce函数中对记录进行缓存。当L和R中具有相同k的值的记录非常多的时候,这将成为一个严重的负担。一种改进的算法减少了这种负担。

改进版:

在map阶段,每个map还是对一个L的分片或者R的分片进行处理。不过,中间记录的键由标准版的仅仅将k的值作为键的值改为由k的值加上数据来源(即是来自于L还是来自于R)做为键的值,余下的部分做为记录的值。在此,构造键的时候用户需要保证在reduce端进行排序的时候,R的记录一定都能够排在L的记录前面。然后,用户需要自定义partition函数,确保k值相同的记录能够被分到同一个reduce当中。同时,用户还需要自定义group函数,使group函数只对中间记录键的k部分的值做处理,以确保具有相同k的值的记录能够被送到同一次的reduce调用当中。

这样,由于R的记录都排在L的记录前面,reduce仅仅需要对R的记录作出缓存即可。

预处理:

如果L和R在进行join操作之前就已经完成排序,并根据连接的键进行了划分,那么在进行连接的时候只需要直接把两者对应的数据读入内存,做连接操作即可。在具体实现时,一方的数据可以从map的输入获取,另一方的数据必须手动从HDFS获取。

2、 Broadcast Join(广播连接)

前提假设:
L的容量远大于R的。

算法:
将R放到所有的机器上,然后在Map过程中,将L的分片与R进行连接

3、 Semi-Join (半连接)

半联结实际上是对广播连接做预处理,因为在很多情况下,不是R中所有的记录都需要和L做连接,因此,可以把R中不需要的记录去掉。具体过程不再详述
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: