1 Reduce Join工作原理
Map端的主要工作:为来自不同表或文件的key/value对,打标签以区别不同来源的记录。然后用连接字段作为key,其余部分和新加的标志作为value,最后进行输出。
Reduce端的主要工作:在Reduce端以连接字段作为key的分组已经完成,我们只需要在每一个分组当中将那些来源于不同文件的记录(在Map阶段已经打标志)分开,最后进行合并就ok了。
2 实例
1.需求
id | pid | amount |
---|---|---|
1001 | 01 | 1 |
1002 | 02 | 2 |
1003 | 03 | 3 |
1004 | 01 | 4 |
1005 | 02 | 5 |
1006 | 03 | 6 |
pid | pname |
---|---|
01 | 小米 |
02 | 华为 |
03 | 格力 |
将商品信息表中数据根据商品pid合并到订单数据表中。
id | pname | amount |
---|---|---|
1001 | 小米 | 1 |
1004 | 小米 | 4 |
1002 | 华为 | 2 |
1005 | 华为 | 5 |
1003 | 格力 | 3 |
1006 | 格力 | 6 |
2.需求分析
通过将关联条件作为Map输出的key,将两表满足Join条件的数据并携带数据所来源的文件信息,发往同一个ReduceTask,在Reduce中进行数据的串联.
思路:
把两个文件全部读到map,并且封装到结构体中,使用二次排序,先排pid,如果pid相同,把有名字的排在最前面,通过pid分组,如果pid一样分到同一个组内,组内来自商品的数据排在第一行,然后遍历后面的数据,把第一行的pname join到后面的数据中.
- 代码
ReduceDriver 类
package com.reducejoin;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
/**
* @author andy
* @version 1.0
* @date 2020/3/3 0:44
* @contact [email protected]
* @since JDK 1.8
*/
public class ReduceDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
if (args == null || args.length < 2)
args = new String[]{
"E:\\temp\\input\\reducejoin", "E:\\temp\\output"};
Path path = new Path(args[1]);
Configuration conf = new Configuration();
FileSystem fs = path.getFileSystem(conf);
Job job = Job.getInstance(conf);
try {
if (fs.exists(path))
fs.delete(path, true);
} catch (IllegalArgumentException e) {
e.printStackTrace();