MapReduce 实现 join

在reduce端实现两表的join


reduce side join是一种最简单的join方式,其主要思想如下:


在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源的key/value数据对,对每条数据打一个标签(tag),比如:tag=0表示来自文件File1,tag=2表示来自文件File2。即:map阶段的主要任务是对不同文件中的数据打标签。


在reduce阶段,reduce函数获取key相同的来自File1和File2文件的value list, 然后对于同一个key,对File1和File2中的数据进行join(笛卡尔乘积)。即:reduce阶段进行实际的连接操作。


主要技巧有:

1、在map端,通过读取文件路径识别具体数据是从哪个文件读取的,然后在value里加上这个文件的标签(tag)。

2、在reduce端,通过分离出map加入的tag,识别出数据属于哪个文件,然后使用vector容器存储每个文件的value,最后用两个for循环遍历即可。


简单代码:

public class join extends Configured implements Tool{
	public static class joinmapper extends Mapper<Longwritable, Text, Text, Text>{
		protected void map(Longwritable key, Text value, Context context)
			throws IOException, InterruptedException{
				String filepath = ((FileSplit)context.getInputSplit()).getPath().toString();
				String line = value.toString();
				if (filepath.indexOf("employee") != -1) {
					String[] lines = line.split("\t", 2);
					String company_id = lines[0];
					String employee = lines[1];
					context.write(new Text(company_id), new Text("a:" + employee));
				} else if (filepath.indexOf("salary") != -1) {
					String[] lines = line.split("\t", 2);
					String company_id = lines[0];
					String salary = lines[1];
					context.write(new Text(company_id), new Text("b:" + salary));
				}
			}
	}
	
	public static class joinreduce extends Reducer<Text, Text, Text, Text> {
		protected void reduce(Text key, Iterable<Text> values, Context context)
			throws IOException, InterruptedException{
				Vector<String> a = new Vector<String>();
				Vector<String> b = new Vector<String>();
				
				for (Text value : values) {
					String line = value.toString();
					String[] lines = line.split(":");
					if (lines[0] == "a"){
						a.add(lines[1]);
					} else if (lines[0] == "b"){
						b.add(lines[1]);
					}
				}
				
				for (int i=0; i<a.size(); i++) {
					for (int j=0; j<b.size(); j++) {
						context.write(key, new Text(a.get(i) + '\t' + b.get(j)));
					}
				}
			}
	}
	
	public int run(String[] args) throws Exception {
		Configuration conf = getConf();
		Job job = new Job(conf, "join");
		
		job.setJarByClass(join.class);
		job.setMapperClass(joinmapper.class);
		job.setReducerClass(joinreduce.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		
		FileInputFormat.addInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		return job.waitForCompletion(true) ? 0 : 1;
	}
	
	public static void main(String[] args) throws Exception{
		int res = ToolRunner.run(new Configuration(), new join(), args);
		System.exit(res);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值