join
1.map 端 join
应用于一个大文件和一个小文件的场景,小文件可以直接读取到内存中,这样每个mappertask都可以有一份小文件的数据,每次map处理数据从大文件中读取一条数据跟小文件中比对,如果有key与之对应,那么相连之后输出
下面是一个简单案例部分代码
小文件的路径需要在驱动类中指定
map端
2.reduce端join
应用于两个大文件的场景,在map阶段对两个文件同时进行读取,在获得数据的同时为其打上“标签”(用来区分两个不同的文件中的数据),然后context.write写出;在reduce阶段,对key相同但是来自于不同文件的一组value数据进行join连接(整合输出)
具体实现部分代码如下
这里之所以重写setup方法是因为setup方法执行在map前
reduce阶段根据标签进行整合输出
多个join联合使用
共同好友问题:
A:B,C,D,F,E,O
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
F:A,B,C,D,E,O,M
用户:用户的好友1,用户的好友2
求出用户两两之间共同好友都有谁?
我们先来分析一下
下面是具体实现代码
job1mapper
package com.bd2001.more_join.job1;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Job1Mapper extends Mapper<LongWritable, Text,Text,Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//读取数据并分割、然后输出
// A:D,E,I,G,B
//key:好友
//value:拥有这个好友的用户
String[] str = value.toString().split(":");
String user = str[0];
List<String> list = Arrays.asList(str[1].split(","));
for (String s : list) {
context.write(new Text(s),new Text(user));
}
}
}
job1reducer
package com.bd2001.more_join.job1;
import org.apache.hadoop.io.Text;