hadoop map端join

本文介绍使用Hadoop MapReduce实现Map端联结的方法,通过将小表缓存到内存中,实现大表与小表的数据联结。具体示例为结合sales与accounts两个表,统计用户的消费次数与总额。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   map端的联结比reduce端的联结实现起来复杂,而且限制也多,一般我们将小表置于内存中, 对于大表的一个纪录我们在内存中查找即可。

   改例子摘自hadoop基础教程, 我们实现sales和accounts的联结, 其中sales记录的顾客的销售信息,accounts纪录的是用户的账户信息,我们的目的是统计每个用户消费的次数和消费总额。

  数据如下:

  sales.txt

  

002 12.29   2004-07-02
004 13.42   2005-12-20
003 499.99  2010-12-20
001 78.95   2012-04-02
002 21.99   2006-11-30
002 93.45   2008-09-10
001 9.99    2012-05-17

  accounts.txt

002 Abigail SmithPremium    2004-07-13
003 April StevensStandard   2010-12-20
004 Nasser HafezPremium 2001-04-23

代码如下:  

import java.io.*;
import java.util.*;

import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class MapJoin {
	public static class MapJoinMapper extends Mapper<Object, Text, Text, Text> {
		public Map<String, String> joinData = new HashMap();
		//执行连接操作
		public void map(Object key, Text value, Context context) throws IOException, InterruptedException{
			String[] values = value.toString().split("\t");
			context.write(new Text(joinData.get(values[0])), value);
		}
		//加载小表
		public void setup(Context context) throws IOException, InterruptedException{
			Path[] path = DistributedCache.getLocalCacheFiles(context.getConfiguration());
			BufferedReader reader = new BufferedReader(new FileReader(path[0].toString()));
			String str = null;
			while((str = reader.readLine()) != null) {
				String[] s = str.split("\t");
				joinData.put(s[0], s[1]);
			}	
		}
	}
	
	public static class MapJoinReducer extends Reducer<Text, Text, Text, Text> {
		public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException{
			int ci = 0;
			double total = 0.0;
			for(Text val : values) {
				ci ++;
				String[] v = val.toString().split("\t");
				total += Float.parseFloat(v[1]);
			}
			String str = String.format("%d\t%f", ci, total);
			context.write(key, new Text(str));
		}
	}	

	public static void main(String[] args) throws Exception{
		Configuration conf = new Configuration();
		DistributedCache.addCacheFile(new Path(args[1]).toUri(), conf);
		
		Job job = new Job(conf, "MapJoin");
		//设置相关类
		job.setJarByClass(MapJoin.class);
		job.setMapperClass(MapJoinMapper.class);
		job.setReducerClass(MapJoinReducer.class);

		//设置map输出格式
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		
		//设置输入输出文件
		FileInputFormat.addInputPath(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[2]));

		//等待作业执行完毕
		System.exit(job.waitForCompletion(true)?0:1);
	}
}

  

转载于:https://www.cnblogs.com/xingxing1024/p/7466262.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值