内连接
两个文件 显示两个文件的数据
根据两个文件的数据进行判断
读取每一行数据
数据长度==2 那么就是第一个文件
长度==3那么就是第二个文件
第一个文件使用a#开头
第二个文件使用b#开头
两个文件使用相同的key value进行合并
获取以为开头a 并进行切分
获取以b开头 并进行切分
把切的数据封装 根据key相同聚合value
package com.hnxy.mr.join;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import com.hnxy.mr.entity.AreaInfoWritable;
import com.hnxy.mr.entity.WordWritable;
import com.hnxy.mr.max.MaxMinWord;
import com.hnxy.mr.max.MaxMinWord.MWReducer;
public class InnerJoin extends Configured implements Tool {
// 1 北京
// 1 2010 1962
// 合并查询
public static class InnerJoinMapper extends Mapper<LongWritable, Text, Text, Text> {
// 定义变量
private String str = "";
private String[] strs = null;
// 定义输出值
private Text outkey = new Text();
private Text outval = new Text();
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
// 有两个文件 一个是两个字段一个是三个字段
// 首先获得每一行数据
strs = value.toString().split("\t");
if (strs.length == 2 && null != strs) {
// id
outkey.set(strs[0]);
// 省份信息
outval.set("a#" + strs[1]);
// 写入这一行数据
context.write(outkey, outval);
} else if (strs.length == 3 && null != strs) {
// id
outkey.set(strs[0]);
outval.set("b#" + strs[1] + "\t" + strs[2]);
// 写入一个数据
context.write(outkey, outval);
} else {
context.getCounter("erro_line", "count").increment(1);
}
}
}
public static class InnerJoinReducer extends Reducer<Text, Text, AreaInfoWritable, NullWritable> {
// 定义返回值对象
private AreaInfoWritable outkey = new AreaInfoWritable();
private String aname = null;
private List<String> year = new LinkedList<String>();
private List<String> count = new LinkedList<String>();
private String tmpSplit = null;
@Override
protected void reduce(Text key, Iterable<Text> values,
Reducer<Text, Text, AreaInfoWritable, NullWritable>.Context context)
throws IOException, InterruptedException {
// 先按照a b切 在根据b的 按照\t切分
year.clear();
count.clear();
aname = null;
for (Text t : values) {
if (t.toString().startsWith("a")) {
// 省份信息
aname = t.toString().split("#")[1];
} else if (t.toString().startsWith("b")) {
tmpSplit = t.toString().split("#")[1];
year.add(tmpSplit.split("\t")[0]); // 年
count.add(tmpSplit.split("\t")[1]); // 人
}
}
// 判断是否失效
if (year.size() > 0 && count.size() > 0 && null != aname && !aname.trim().equals("")) {
for (int i = 0; i < year.size(); i++) {
outkey.setAid(Long.parseLong(key.toString()));
outkey.setAreaName(aname);
outkey.setCount(Long.parseLong(count.get(i)));
outkey.setYear(year.get(i));
// 写入数据
context.write(outkey, NullWritable.get());
}
}
}
}
@Override
public int run(String[] args) throws Exception {
// 创建方法的返回值
int count = 0;
// 创建核心配置对象
Configuration conf = this.getConf();
// 创建一个任务
Job job = Job.getInstance(conf, "maxword");
// 配置任务打包类
job.setJarByClass(InnerJoin.class);
// 设置MapReduce类
job.setMapperClass(InnerJoinMapper.class);
job.setReducerClass(InnerJoinReducer.class);
// 设置 map 阶段 和 reduce 节点的 输出数据类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(AreaInfoWritable.class);
job.setOutputValueClass(NullWritable.class);
// 设置文件路径
Path in = new Path(args[0]);
Path out = new Path(args[1]);
// 设置hdfs操作对象
FileSystem fs = FileSystem.get(conf);
// 绑定文件输出输入目录
FileInputFormat.addInputPath(job, in);
FileOutputFormat.setOutputPath(job, out);
// 自动删除
if (fs.exists(out)) {
fs.delete(out, true);
// 提示
System.out.println(job.getJobName() + "'s Path Output is deleted");
}
// 执行
boolean con = job.waitForCompletion(true);
// 返回
if (con) {
System.out.println("成功");
} else {
System.out.println("失败");
}
return 0;
}
public static void main(String[] args) throws Exception {
System.exit(ToolRunner.run(new InnerJoin(), args));
}
}