CommonJoin和MapJoin

来源:互联网 发布:数据压缩算法 编辑:程序博客网 时间:2024/06/14 08:57

CommonJoin和MapJoin简介

CommonJoin即是传统思路实现Join的方法,性能差,涉及到了shuffle的过程
CommonJoin/shuffleJoin/reduceJoin都是指同一个的
MapJoin也叫做BroadCastJoin,但是MapJoin是不会有reduce阶段和shuffle阶段

重点对CommonJoin和MapJoin实现,通过MapReduce实现的,有助于我们理解后续的Hive中的Join实现

CommonJoin的MapReduce实现

CommonJoinMap

package   com.bigdata.commonjoin;import  org.apache.hadoop.io.LongWritable;import  org.apache.hadoop.io.Text;import  org.apache.hadoop.mapreduce.Mapper;import  org.apache.hadoop.mapreduce.lib.input.FileSplit;import java.io.IOException;public    class CommonJoinMap  extends  Mapper<LongWritable ,Text,Text,Text>{     protected  void map(LongWritable  key ,Text  value,Mapper<LongWritable,Text,Text,Text>.Context  context) throws  IOException,InterruptedException{  //获取输入文件的全路径和名称  FileSplit  fileSplit=(FileSplit)context.getInputSplit();  String path=fileSplit.getPath().toString();      //获取输入记录的字符串  String  line=value.toString();//处理来自emp表中的记录if(path.contains("emp")){ //按照空格切割 String[] values=line.split(" "); //获取emp表中的部门编号和员工名字 String   deptNo=values[7]; String   empName=values[1];//把结果写出去,打标签context.write(new Text(deptNo),new Text("a#"+empName));}else if(path.contains("dept")){    //按空格符号进行切割    String[]  values=line.split(" ");    //获取dept表中的部门编号,部门名称,城市    String  deptNo=values[0];    String deptName=values[1];    String  city=values[2];//把结果写出去,打标签context.write(new Text(deptNo),new Text("b#"+deptName   +"  "+city));}}}CommonJoinReducepackage com.bigdata.commonjoin;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;import java.util.Vector;public  class CommonJoinReduce  extends  Reducer<Text,Text,Text,Text>{protected void reduce(Text key ,Iterable<Text>  values,Reducer<Text,Text,Text,Text>.Context  context) throws  IOException,InterruptedException{//用于存放来自emp表的数据Vector<String> vectorA=new Vector<String>();//用于存放来自dept表的数据Vector<String>  vectorB=new Vector<String>();//迭代集合数据for(Text val:values){ //将集合中的数据添加到相应的Vector中去 //根据标签,将a#和b#之后的数据全部提取出来 //相当于去除标签 if(val.toString().startsWith("a#")){   vectorA.add(val.toString().substring(2));}else  if(val.toString().startsWith("b#")){    vectorB.add(val.toString().substring(2));}}//获取俩个Vector集合的长度int sizeA=vectorA.size();int sizeB=vectorB.size();//遍历俩个向量,将结果写出去for(int  i=0;i<sizeA;i++){    for(int  j=0;j<sizeB;j++){       context.write(key,new Text(" "+vectorA.get(i)+" "+vectorB.get(j)));  }}}}CommonJoinDriverpackage   com.bigdata.commonjoin;import  org.apache.hadoop.conf.Configuration;import  org.apache.hadoop.fs.FileSystem;import  org.apache.hadoop.fs.Path;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.input.TextInputFormat;import  org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import  org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;import  java.net.URL;public  class    CommonJoinDriver{ public statkic  void main(String[]  args) throws Exception{       //定义输入路径       String  INPUT_PATH="/input/*";       //定义输出路径       String   OUT_PATH="/out/commonjoin_out";         //创建配置信息       Configuration   conf=new Configuration();       //创建文件系统       FileSystem  fileSystem=FileSystem.get(new URI(OUT_PATH),conf);       //如果输出目录存在,我们就删除       if(fileSystem.exists(new Path(OUT_PATH))){            fileSystem.delete(new Path(OUT_PATH),true);     }   // 创建任务    Job  job=new Job(conf,CommonJoinDriver.class.getName());    //打成jar运行,这句话是关键    job.setJarByClass(CommonJoinDriver.class);    //设置输入目录和设置输入数据格式化的类    FileInputFormat.setInputPaths(job,INPUT_PATH);    job.setInputFormatClass(TextInputFormat.class);    //设置自定义Mapper类和设置map函数输出数据的key和value类型    job.setMapperClass(CommonJoinMap.class);    job.setMapOutputKeyClass(Text.class);    job.setMapOutputValueClass(Text.class);     //指定Reducer类和输出key和value的类型   job.setReducerClass(CommonJoinReduce.class);   job.setOutputKeyClass(Text.class);   job.setOutputValueClass(Text.class);   //指定输出的路径和设置输出的格式化    FileOutputFormat.setOutputPath(job,new Path(OUT_PATH));       job.setOutputFormatClass(TextOutputFormat.class);    //提交作业,退出    System.exit(job.waitForCompletion(true)?0:1);}}

MapJoin的MapReduce实现

MapJoinMapper

“`
package com.bigdata.mapjoin;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apahce.hadoop.mapreduce.filecache.DistributedCache;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class MapJoinMapper extends Mapper