MapReduce Join操作

Mapreduce连接

1、reduce side join

在reduce端进行表的连接,该方法的特点就是操作简单,缺点是map端shffule后传递给reduce端的数据量过大,极大的降低了性能
连接方法:
(1)map端读入输入数据,以连接键为Key,待连接的内容为value,但是value需要添加特别的标识,表示的内容为表的表示,即若value来自于表1,则标识位设置为1,若来自表2,则设置为2,然后将map的内容输出到reduce
(2)reduce端接收来自map端shuffle后的结果,即<key, values>内容,然后遍历values,对每一个value进行处理,主要的处理过程是:判断每一个标志位,如果来自1表,则将value放置在特地为1表创建的数组之中,若来自2表,则将value放置在为2表创建的数组中,最后对两个数组进行求笛卡儿积,然后输出结果,即为最终表的连接结果。
2、map side join
在map端进行表的连接,对表的大小有要求,首先有一个表必须足够小,可以读入内存,另外的一个表很大,与reduce端连接比较,map端的连接,不会产生大量数据的传递,而是在map端连接完毕之后就进行输出,效率极大的提高
连接方法:
(1)首先要重写Mapper类下面的setup方法,因为这个方法是先于map方法执行的,将较小的表先读入到一个HashMap中。
(2)重写map函数,一行行读入大表的内容,逐一的与HashMap中的内容进行比较,若Key相同,则对数据进行格式化处理,然后直接输出。

Reduce侧连接

使用分布式缓存API,完成两个数据集的连接操作

MapReduce连接取决于数据集的规模及分区方式
如果一个数据集很大而另外一个数据集很小,小的分发到集群中的每一个节点

mapper阶段读取大数据集中的数据
reducer获取本节点上的数据(也就是小数据集中的数据)并完成连接操作

步骤
将hdfs上的文件加入分布式缓存

URI cachepath = new Path("hdfs://master:9000/forms/address.dat").toUri();
job.setCacheFiles(new URI[]{cachepath});

之后在map/reduce函数中可以通过context来访问到缓存的文件,一般是重写setup方法来进行初始化

Map<String, String> addMap = new HashMap<String, String>();
protected void setup(Context context)
	         throws java.io.IOException, java.lang.InterruptedException {
			 
			 URI uri = context.getCacheFiles()[0];
			 Path path = new Path(uri.toString());
			 Configuration conf = context.getConfiguration();
			 FileSystem fs = path.getFileSystem(conf);
			 
			 @SuppressWarnings("resource")
			 LineReader linereader = new LineReader(fs.open(path));
			 Text t = new Text();
			 while(linereader.readLine(t) > 0) {
				 String[] tokens = t.toString().split(",");
				 if(tokens!=null && tokens.length==2)
				 addMap.put(tokens[0], tokens[1]);
			 }
		 }
protected void reduce(Text key, Iterable<Text> values, Context context)
				throws IOException, InterruptedException {
			 
			 if(values == null) return;
			 String v = addMap.get(values.iterator().next().toString());
			 out_key.set(key);
			 out_value.set(v);
			 context.write(out_key, out_value);
		 }     

Map侧的连接

两个数据集中一个非常小,可以让小数据集存入缓存。在作业开始这些文件会被复制到运行task的节点上。 一开始,它的setup方法会检索缓存文件。

Map侧连接需要满足条件

与reduce侧连接不同,Map侧连接需要等待参与连接的数据集满足如下条件

1.除了连接键外,所有的输入都必须按照连接键排序。
输入的各种数据集必须有相同的分区数。
所有具有相同键的记录需要放在同一分区中。
当Map任务对其他Mapreduce作业的结果进行处理时(Cleanup时),Map侧的连接条件都自动满足
CompositeInputFormat类用于执行Map侧的连接,而输入和连接类型的配置可以通过属性指定

2.如果其中一个数据集足够小,旁路的分布式通道可以用在Map侧的连接中

总结

1.避免生成太多依赖I/O的map任务,数量由输入决定
2.作业加速主要来源于Map任务,有更高的并行度
3.Combiner对效率的提高,不仅在map reduce任务之间的数据传输,而且体现在降低了map侧I/O负载
4.自定义分区器可以在不同的reduce之间做负载均衡
5.分布式缓存对于小文件场景很有用,但应该避免过多或大的文件存储在缓存中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值