Hadoop基础-MapReduce的Join操作

                                    作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.连接操作Map端Join(适合处理小表+大表的情况)

    no001    12.3
no002 18.8
no003 20.0
no004 50.0
no005 23.1
no006 39.0
no007 5.0
no008 6.0

orders.txt 文件内容

    linghunbaiduren
yinzhengjie
alex
linhaifeng
wupeiqi
xupeicheng
changqiling
laowang

customers.txt 文件内容

1>.MapJoinMapper.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.map; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map; /**
* 输出KeyValue
* key是组合后的数据
* value空
*
*/
public class MapJoinMapper extends Mapper<LongWritable,Text,Text,NullWritable> { Map<Integer,String> map = new HashMap<Integer, String>(); /**
*
*setup方法是在map方法之前执行,它也是map方法的初始化操作.
*
*/
@Override
protected void setup(Context context) throws IOException, InterruptedException {
//通过上下文,得到conf
Configuration conf = context.getConfiguration();
//通过conf获取自定义key
String file = conf.get("customer.file");
//读取customer数据
FileSystem fs = FileSystem.get(conf);
FSDataInputStream fis = fs.open(new Path(file));
InputStreamReader reader = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(reader);
String line = null;
byte[] buf = new byte[1024];
while((line = br.readLine()) != null){
String[] arr = line.split("\t");
int id = Integer.parseInt(arr[0]);
String name = arr[1];
//1 tom
//2 tomas
map.put(id,name);
}
} /**
* 通过
* oid orderno price cid
* 8 no008 6.0 1
*
* 得到
* cid cname orderno price
* 1 tom no008 6.0
*/ @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] arr = line.split("\t"); String orderno = arr[1];
String price = arr[2];
int cid = Integer.parseInt(arr[3]); String name = map.get(cid);
//拼串操作
String outKey = cid + "\t" + name + "\t" + orderno + "\t" + price + "\t";
//
context.write(new Text(outKey), NullWritable.get());
}
}

2>.MapJoinApp.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.map; 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.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class MapJoinApp { public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
//自定义一个变量名"customer.file",后面的文件是其具体的值,这里设置后可以在Mapper端通过get方法获取改变量的值。
conf.set("customer.file", "D:\\10.Java\\IDE\\yhinzhengjieData\\customers.txt");
conf.set("fs.defaultFS","file:///");
FileSystem fs = FileSystem.get(conf);
Job job = Job.getInstance(conf);
job.setJarByClass(MapJoinApp.class);
job.setJobName("Map-Join");
job.setMapperClass(MapJoinMapper.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
FileInputFormat.addInputPath(job,new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\orders.txt"));
Path outPath = new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\out");
if (fs.exists(outPath)){
fs.delete(outPath);
}
FileOutputFormat.setOutputPath(job,outPath);
job.waitForCompletion(true);
}
}

3>.验证结果是否正确

二.连接操作Reduce端Join之组合Key实现(适合处理大表+大表的情况)

    no001    12.3
no002 18.8
no003 20.0
no004 50.0
no005 23.1
no006 39.0
no007 5.0
no008 6.0

orders.txt 文件内容

    linghunbaiduren
yinzhengjie
alex
linhaifeng
wupeiqi
xupeicheng
changqiling
laowang

customers.txt 文件内容

  以上两个文件的指定路径如下:(输入路径)

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.reduce; import org.apache.hadoop.io.WritableComparable; import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; public class CompKey implements WritableComparable<CompKey> {
//定义客户id
private int cid;
//定义标识
private int flag; public int compareTo(CompKey o) {
//如果cid相等
if (this.getCid() == o.getCid()) {
//比较flag
return this.getFlag() - o.getFlag();
}
return this.getCid() - o.getCid();
} //定义序列化
public void write(DataOutput out) throws IOException {
out.writeInt(cid);
out.writeInt(flag);
} //定义反序列化
public void readFields(DataInput in) throws IOException {
cid = in.readInt();
flag = in.readInt();
} public int getCid() {
return cid;
} public void setCid(int cid) {
this.cid = cid;
} public int getFlag() {
return flag;
} public void setFlag(int flag) {
this.flag = flag;
} @Override
public String toString() {
return cid + "," + flag;
}
}

CompKey.java(组合Key实现)

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.reduce; import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator; public class MyGroupingComparator extends WritableComparator { public MyGroupingComparator() {
super(CompKey.class, true);
} @Override
public int compare(WritableComparable a, WritableComparable b) { CompKey ck1 = (CompKey) a;
CompKey ck2 = (CompKey) b; int cid1 = ck1.getCid();
int cid2 = ck2.getCid(); return cid1 - cid2;
}
}

MyGroupingComparator.java (分组对比器实现)

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.reduce; import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit; import java.io.IOException; public class ReduceJoinMapper extends Mapper<LongWritable, Text, CompKey, Text> { String fileName; @Override
protected void setup(Context context) throws IOException, InterruptedException {
//得到输入切片
InputSplit split = context.getInputSplit();
FileSplit fileSplit = (FileSplit) split; //得到切片文件名或路径
fileName = fileSplit.getPath().getName();
} @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString();
String[] arr = line.split("\t"); //判断文件是否包含"customers"。
if (fileName.contains("customers")) {
int cid = Integer.parseInt(arr[0]);
CompKey ck = new CompKey();
ck.setCid(cid);
ck.setFlag(0);
context.write(ck, value);
} else {
int cid = Integer.parseInt(arr[3]);
CompKey ck = new CompKey();
ck.setCid(cid);
ck.setFlag(1);
context.write(ck, value);
}
}
}

ReduceJoinMapper.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.reduce; import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException;
import java.util.Iterator; public class ReduceJoinReducer extends Reducer<CompKey, Text, Text, NullWritable> { /**
* 通过
* oid orderno price cid
* 8 no008 6.0 1
* <p>
* 得到
* cid cname orderno price
* 1 tom no008 6.0
*/
@Override
protected void reduce(CompKey key, Iterable<Text> values, Context context) throws IOException, InterruptedException { //初始化迭代器
Iterator<Text> it = values.iterator(); //将while指针指向第一条之后
String cust = it.next().toString(); //继上一条之后读取
while(it.hasNext()){
String[] arr = it.next().toString().split("\t");
String orderno = arr[1];
String price = arr[2];
String newLine = cust.toString() + "\t" + orderno + "\t" + price;
context.write(new Text(newLine), NullWritable.get()); }
}
}

ReduceJoinReducer.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.join.reduce; 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.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class ReduceJoinApp { public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","file:///");
FileSystem fs = FileSystem.get(conf);
Job job = Job.getInstance(conf);
job.setJarByClass(ReduceJoinApp.class);
job.setJobName("Reduce-Join");
job.setMapperClass(ReduceJoinMapper.class);
job.setReducerClass(ReduceJoinReducer.class);
job.setGroupingComparatorClass(MyGroupingComparator.class);
//map的输出k-v
job.setMapOutputKeyClass(CompKey.class);
job.setMapOutputValueClass(Text.class); //reduce的k-v
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class); //指定输入的文件路径
FileInputFormat.addInputPath(job,new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\input\\"));
//指定输出的文件路径
Path outPath = new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\output");
if (fs.exists(outPath)){
fs.delete(outPath);
}
FileOutputFormat.setOutputPath(job,outPath); job.setNumReduceTasks(2);
job.waitForCompletion(true);
}
}

ReduceJoinApp.java 文件内容

  以上代码执行结果如下:(输出路径)

Hadoop基础-MapReduce的Join操作的更多相关文章

  1. Hadoop基础-MapReduce的常用文件格式介绍

    Hadoop基础-MapReduce的常用文件格式介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MR文件格式-SequenceFile 1>.生成SequenceF ...

  2. Hadoop基础-MapReduce的排序

    Hadoop基础-MapReduce的排序 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce的排序分类 1>.部分排序 部分排序是对单个分区进行排序,举个 ...

  3. Hadoop基础-MapReduce的Partitioner用法案例

    Hadoop基础-MapReduce的Partitioner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Partitioner关键代码剖析 1>.返回的分区号 ...

  4. Hadoop基础-MapReduce的Combiner用法案例

    Hadoop基础-MapReduce的Combiner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编写年度最高气温统计 如上图说所示:有一个temp的文件,里面存放 ...

  5. Hadoop基础-MapReduce的工作原理第二弹

    Hadoop基础-MapReduce的工作原理第二弹 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Split(切片)  1>.MapReduce处理的单位(切片) 想必 ...

  6. Hadoop基础-MapReduce的工作原理第一弹

    Hadoop基础-MapReduce的工作原理第一弹 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在本篇博客中,我们将深入学习Hadoop中的MapReduce工作机制,这些知识 ...

  7. Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码

    Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文主要是记录一写我在学习MapReduce时的一些 ...

  8. Hadoop基础-通过IO流操作HDFS

    Hadoop基础-通过IO流操作HDFS 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.上传文件 /* @author :yinzhengjie Blog:http://www ...

  9. Hadoop基础-MapReduce的数据倾斜解决方案

    Hadoop基础-MapReduce的数据倾斜解决方案 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据倾斜简介 1>.什么是数据倾斜 答:大量数据涌入到某一节点,导致 ...

随机推荐

  1. Security7:管理SQL Server Agent的权限

    SQL Server Agent对象包括警报(Alert),操作员(Operator),Job,调度(Schedule)和代理(Proxy),SQL Server使用msdb系统数据库管理Agent ...

  2. Svn 提示错误:previous operation has not finished 解决方案

    svn提交遇到恶心的问题,可能是因为上次cleanup中断后,进入死循环了. 解决方案: 找到你项目的.svn文件,查看是否存在wc.db 网上下载SQLite Expert工具,手动打开wc.db, ...

  3. kafka的简单理解

    经典组合: Flume+Kafka+Storm+HDFS/HBase Flume:分布式采集 Kafka:分布式缓存 Kafka简介: 一种分布式的.基于发布/订阅的消息系统(Scala编写的) Ka ...

  4. 安装loadrunner11出现Microsoft Visual c++2005 sp1安装失败

    本文转至别处,网上大神多

  5. mac10.12.6系统配置clion编写CMakeLists文件运行opencv3

    按照mac10.12.6系统使用cmake安装opencv3.3.0+opencv_contrib-3.3.0下载编译安装好了文件以后,装好clion编译器,新建C++可执行工程,编写代码 opecv ...

  6. 关于最近996.icu的一点感想

    最近这个996.ICU的话题讨论的火热,特别是一些业界大佬有直言不讳的说就是要996,有的弄些鸡汤文把996说成年轻人就该这样的.作为一个普通的码农,实在是看不下去了,在这里说些自己的看法,希望年轻人 ...

  7. 桌面输入法评测报告 之 搜狗拼音输入法vs必应拼音输入法

    输入法是电脑用户不可或缺的软件,它几乎无时无刻不陪伴在使用者的身旁.一个优秀的输入法,应该满足客户对使用体验以及效率的需求.我们小队的任务便是对当今最为常用的两种输入法: 搜狗拼音输入法和必应拼音输入 ...

  8. 《Linux内核分析与设计》读书笔记二

    第五章 5.1 与内核通信57 系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: 首先它为用户空间提供了一种硬件的抽象接口,举例来说当需要读写文件的时候,应用程序就可以不去管 ...

  9. 小组成员及其git链接

    组名:天天向上 Github仓库:https://github.com/lvcaixia/test 组长:吕彩霞 201303014109(计科高职13-3) 第一题   https://github ...

  10. OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch

    文章名称:OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch Op ...