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. mysql 配置 root 远程访问

    来源: https://www.cnblogs.com/24la/p/mariadb-remoting-access.html 首先配置允许访问的用户,采用授权的方式给用户权限 GRANT ALL P ...

  2. 【原创】梵高油画用深度卷积神经网络迭代10万次是什么效果? A neural style of convolutional neural networks

    作为一个脱离了低级趣味的码农,春节假期闲来无事,决定做一些有意思的事情打发时间,碰巧看到这篇论文: A neural style of convolutional neural networks,译作 ...

  3. 阿里云rds 备份和还原

    阿里云rds 备份和还原 转发:https://www.cnblogs.com/lin1/p/8617764.html 转发:https://help.aliyun.com/knowledge_det ...

  4. 小白之selenium+python关于cookies绕开登录1

    cookie是存储在本地浏览器目录的一些信息,详细一点的话可以查看度娘,按照我的理解就是将信息存储在本地,访问网站的时候,网站的服务器会优先读取本地目录位置的信息,然后做出相对的反应.这就是为什么有的 ...

  5. redis在php中常用的语法(转)

    String 类型操作 string是redis最基本的类型,而且string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 $redis-> ...

  6. 使用kubeadm安装kubernetes高可用集群

    kubeadm安装kubernetes高可用集群搭建  第一步:首先搭建etcd集群 yum install -y etcd 配置文件 /etc/etcd/etcd.confETCD_NAME=inf ...

  7. Appium+Python3+ Android入门

    前言: Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用. 一.环境配置 1.安装Node.js https://nodejs.o ...

  8. PAT甲题题解-1006. Sign In and Sign Out (25)-找最小最大

    判断哪个人最早到,哪个人最晚走水,就是找最大值最小值 #include <iostream> #include <cstdio> #include <algorithm& ...

  9. 实验---反汇编一个简单的C程序(杨光)

    反汇编一个简单的C程序 攥写人:杨光  学号:20135233 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163 ...

  10. 2013 C#单元测试

    首先安装Unit Test Generator. 点击拓展和更新——>联机搜索Unit Test Generator 新建项目 新建一个测试类  add函数 选定test 类名 ——>右键 ...