我的hadoop程序之----------------------DataJoinDC------------多表链接的分布式缓存实现(新版API)

本文详细介绍了如何使用Hadoop的分布式缓存功能来优化多表链接任务,通过将小表作为分布式缓存,显著减少了数据传输开销。文中还提供了具体的程序代码示例,包括Mapper类的setup函数实现以及参数args的正确使用方法。

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

完成的任务多表链接,前面已经实现过一次了,这次使用hadoop的分布式缓存DistributedCache来实现,节省了map之后要传输给reducer大量的数据开销,使用DistributedCache的前提条件是,链接的两个表,有一个是小表,另一个是大表,将小表放入DistributedCache中,从而实现将小表分布式存储在每个map节点,节省了大部分传出开销,这里的饿例子只是一个测试用的小例子,可以知道表一公司表可以做的很大,但是表二地址表应该不会是太大的。

表一:大表,左侧是公司名称,右侧是地址ID

Beijing Red Star,1
Shenzhen Thunder,3
Guangzhou Honda,2
Beijing Rising,1
Guangzhou Development Bank,2
Tencent,3
Back of Beijing,1
表二:小表 ,左侧是地址ID,右侧是地址名称

1 Beijing
2 Guangzhou
3 Shenzhen
4 Xian


//需要解释一下Mapper类的关于setup函数,在Hadoop in Action中,用的是老版的API,使用的Configure函数,我们查阅源码可以发现,新版的API已经舍弃了将Job和Configuration放在一个Jobconf中使用的方法,分开为Job和Configuration两个类

//所以,在使用新版API时,建议大家一定要多多查看源码,看看其中到底是怎么实现的,其实hadoop的源码java实现都很平易近人易懂的。
//这里我们查阅Mapper的源码可以发现,Mapper类加载时会执行四个函数:1、protected void setup(Context context)
//                                                        2、protected void map(KEYIN key, VALUEIN value, Context context)
//                                                        3、protected void cleanup(Context context)
//                                                        4、public void run(Context context)

//这里的setup函数代替了老板中集成了JobConfigure的Configure函数,也体现了该团队要将Job和Configuration分离的思想,所以这里使用到了setup函数


自己写的程序源码:

package bin;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;


public class MTJoinDC extends Configured implements Tool{

	public static class MTJoinDCMap extends Mapper<Text, Text, Text, Text>{
		private HashMap<String, String> joinData =new HashMap<String,String>();

		//定义方法setup分割文件中的每一行,","前的字符串放在tokens[0]中,","后的字符串放在tokens[1]中
		public void setup(Context context) {
			try {
				Path[] cacheFiles=DistributedCache.getLocalCacheFiles(context.getConfiguration());//设置分布式cache的路径
				if (cacheFiles!=null && cacheFiles.length!=0) {
					String lineString;
					String[] tokens;
					BufferedReader bReader=new BufferedReader(new FileReader(cacheFiles[0].toString()));
					try {
						while ((lineString=bReader.readLine())!=null) {
							tokens=lineString.split(" ",2);
							joinData.put(tokens[0], tokens[1]);
						}
					}finally{
						bReader.close();
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//实现mapper接口中的抽象方法map()
		public void map(Text key,Text value,Context context) {
			String joinValue=joinData.get(value.toString());//这里是value.toString(),用value不行。。。。。。。。。。!!!
			if (null!=joinValue) {
				try {
					context.write(key, new Text(joinValue));
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	

	@Override
	/*
	 * 通过主函数中 ToolRunner.run(new Configuration(), new DistributedCacheJoin(), args);  方法调用
	 * (non-Javadoc)run方法是 Tool接口中定义的抽象方法,在实现该类的时候,一定要实现run方法
	 * @see org.apache.hadoop.util.Tool#run(java.lang.String[])
	 */
	public int run(String[] args) throws Exception {//具体实现作业分配
		Configuration configuration=getConf();//全局使用同一个
		
		Job job=new Job(configuration, "MTJoinDC");
		job.setJarByClass(MTJoinDC.class);
		
		DistributedCache.addCacheFile(new Path(args[0]).toUri(), job.getConfiguration());
		
		Path in=new Path(args[1]);
		Path out= new Path(args[2]);
		
		FileInputFormat.setInputPaths(job, in);
		FileOutputFormat.setOutputPath(job, out);
		
		job.setMapperClass(MTJoinDCMap.class);
		job.setNumReduceTasks(0);//不进行Reduce操作
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		job.setInputFormatClass(org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);
		job.getConfiguration().set("mapreduce.input.keyvaluelinerecordreader.key.value.separator", ",");
		System.exit(job.waitForCompletion(true)?0:1);
		return 0;
	}
	
	public static void main(String[] args) throws Exception {
		int res=ToolRunner.run(new Configuration(),new MTJoinDC(), args);//参数:新建Configuration,其中的tool参数传递的是主类
		System.exit(res);
	}

}


运行时,了解程序代码真正含义的人都可写出正确的参数args列表,但是初学者,一知半解的可能就比较困难了,在这里提示大家一下:

第一个参数,也就是args[0],是分布式cache中要存放的文件(---------即,那张小表,表二,是setup需要处理的-----------)

第二个参数,也就是args[1],是分布式cache中要存放的文件(---------即,那张大表,表一,map需要处理的输入-----------)

第三个参数就很显然了是你的输出文件。



--------------------------------------------------------------尊重劳动成果尊重原创----------------------------------转载请注明出处,3Q

学习路上困苦实多,得到了网上很多好心人的大方帮助,他们分享了自己遇到的问题和一些经验心得,我从中受益匪浅,在这里我也贡献出自记得一份力量,希望正好学习它的人能够有一些收获,也希望我这个菜鸟能够在跟大家的交流中成长进步。

                                                                                                                                         --------------欣





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值