Hadoop 实例二 Join讲解1: 获取员工所在部门信息

1、原始数据
员工数据
empno    ename    job            mgr    hiredate    sal    comm    deptno    loc
7499    allen    salesman    7698    1981-02-20    1600    300    30    
7782    clark    managers    7639    1981-06-09    2450        10    
7654    martin    salesman    7698    1981-03-20    1250    1400    30    boston
7900    james    clerk    7698    1981-01-09    950        30    
7788    scott    analyst    7566    1981-09-01    3000    100    20    

部门数据
deptno    dname    loc
30    sales    chicago
20    research    dallas
10    accounting    newyork

2、实现的功能类似于
select e.empno,e.ename,d.dname,d.deptno from emp e join dept d on e.deptno=d.deptno;

3、处理join的思路:
       将Join key 当作map的输出key, 也就是reduce的输入key ,  这样只要join的key相同,shuffle过后,就会进入到同一个reduce 的key - value list 中去。
       需要为join的2张表设计一个通用的一个bean.  并且bean中加一个flag的标志属性,这样可以根据flag来区分是哪张表的数据。
       reduce 阶段根据flag来判断是员工数据还是部门数据就很容易了 。而join的真正处理是在reduce阶段。

4、实现中间bean

    存储数据的bean  (由于数据要在网络上传输必须序列化,hadoop处理的时候需要分组和排序,所以要实现WritableComparable接口):

package com.wy.hadoop.join.one;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.WritableComparable;

public class Emplyee implements WritableComparable {
   
   
private String empNo ="";
   
private String empName ="";
   
private String deptNo="";
   
private String deptName="";
   
private int flag =0;
   
   
public Emplyee(){};
   
public Emplyee(String empNo,String empName,String deptNo,String deptName,int flag){
       
this.empNo = empNo;
       
this.empName = empName;
       
this.deptNo = deptNo;
       
this.deptName = deptName;
       
this.flag = flag;
   
}
   
public Emplyee(Emplyee e){
       
this.empNo = e.empNo;
       
this.empName = e.empName;
       
this.deptNo = e.deptNo;
       
this.deptName = e.deptName;
       
this.flag = e.flag;
   
}
   
public String getEmpNo() {
       
return empNo;
   
}

   
public void setEmpNo(String empNo) {
       
this.empNo = empNo;
   
}

   
public String getEmpName() {
       
return empName;
   
}

   
public void setEmpName(String empName) {
       
this.empName = empName;
   
}

   
public String getDeptNo() {
       
return deptNo;
   
}

   
public void setDeptNo(String deptNo) {
       
this.deptNo = deptNo;
   
}

   
public String getDeptName() {
       
return deptName;
   
}

   
public void setDeptName(String deptName) {
       
this.deptName = deptName;
   
}

   
public int getFlag() {
       
return flag;
   
}

   
public void setFlag(int flag) {
       
this.flag = flag;
   
}

   
@Override
   
public void readFields(DataInput input) throws IOException {
       
// TODO Auto-generated method stub
       
this.empNo = input.readUTF();
       
this.empName = input.readUTF();
       
this.deptNo = input.readUTF();
       
this.deptName = input.readUTF();
       
this.flag = input.readInt();
   
}

   
@Override
   
public void write(DataOutput output) throws IOException {
       
// TODO Auto-generated method stub
        output
.writeUTF(this.empNo);
        output
.writeUTF(this.empName);
        output
.writeUTF(this.deptNo);
        output
.writeUTF(this.deptName);
        output
.writeInt(this.flag);
       
   
}

   
@Override
   
public int compareTo(Object o) {
       
// TODO Auto-generated method stub
       
return 0;
   
}
   
@Override
   
public String toString() {
       
String string = this.deptNo+","+this.empNo+","+this.empName+","+this.deptName;
       
return string;
   
}
   
}

5、实现map代码编写

package com.wy.hadoop.join.one;

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class EmpMapper extends Mapper<LongWritable, Text, LongWritable, Emplyee> {

   
@Override
   
protected void map(LongWritable key, Text value,
           
Context context)
           
throws IOException, InterruptedException {
       
String val = value.toString();
       
String[] arr = val.split("\t");
       
System.out.println("arr.length="+arr.length+"   arr[0]="+arr[0]);
       
if(arr.length<=3){//dept
           
Emplyee e = new Emplyee();
            e
.setDeptNo(arr[0]);
            e
.setDeptName(arr[1]);
            e
.setFlag(1);
           
            context
.write(new LongWritable(Long.valueOf(e.getDeptNo())), e);
           
       
}else{//emp
           
Emplyee e = new Emplyee();
            e
.setEmpNo(arr[0]);
            e
.setEmpName(arr[1]);
            e
.setDeptNo(arr[7]);
            e
.setFlag(0);
           
            context
.write(new LongWritable(Long.valueOf(e.getDeptNo())), e);
       
}
       
       
   
}

}

6、实现reduce代码编写

package com.wy.hadoop.join.one;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import com.google.protobuf.ByteString.Output;

public class EmpReducer extends
       
Reducer<LongWritable, Emplyee, LongWritable, Text> {

   
@Override
   
protected void reduce(LongWritable key, Iterable<Emplyee> iter,
           
Context context)
           
throws IOException, InterruptedException {
       
       
Emplyee dept = null;
       
List<Emplyee> list = new ArrayList<Emplyee>();
       
       
for(Emplyee tmp : iter){
           
if(tmp.getFlag()==0){//emp
               
Emplyee emplyee = new Emplyee(tmp);
                list
.add(emplyee);
           
}else {
                dept
= new Emplyee(tmp);
           
}
       
}
       
       
if(dept!=null){
           
for(Emplyee xtmp:list){
                xtmp
.setDeptName(dept.getDeptName());
                context
.write(new LongWritable(0), new Text(xtmp.toString()));
           
}
       
}
       
   
}

   

}

7、实现job调用主函数编写

package com.wy.hadoop.join.one;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class EmplyeeJob extends Configuration implements Tool, Runnable {

   
private String inputPath = null;
   
private String outputPath = null;
   
   
public EmplyeeJob(String inputPath,String outputPath){
       
this.inputPath = inputPath;
       
this.outputPath = outputPath;
   
}
   
public EmplyeeJob(){}
   
   
@Override
   
public Configuration getConf() {
       
// TODO Auto-generated method stub
       
return new Configuration();
   
}

   
@Override
   
public void setConf(Configuration arg0) {
       
// TODO Auto-generated method stub

   
}

   
@Override
   
public void run() {
       
try{
           
String[] args = {this.inputPath,this.outputPath};
           
            start
(args);
           
       
}catch (Exception e) {
            e
.printStackTrace();
       
}

   
}

   
private void start(String[] args)throws Exception{
       
       
ToolRunner.run(new EmplyeeJob(), args);
   
}

   
@Override
   
public int run(String[] args) throws Exception {
       
       
Job job = new Job(getConf(),"emplyeejob");
        job
.setJarByClass(EmplyeeJob.class);
       
        job
.setMapOutputKeyClass(LongWritable.class);
        job
.setMapOutputValueClass(Emplyee.class);
       
        job
.setOutputKeyClass(LongWritable.class);
        job
.setOutputValueClass(Text.class);
       
        job
.setMapperClass(EmpMapper.class);
        job
.setReducerClass(EmpReducer.class);
       
       
FileInputFormat.addInputPath(job, new Path(args[0]));
       
FileOutputFormat.setOutputPath(job, new Path(args[1]));
       
       
boolean success = job.waitForCompletion(true);
       
       
return success?0:1;
   
}

}

package com.wy.hadoop.join.one;

public class JobMain {

   
/**
     * @param args
     */

   
public static void main(String[] args) {
       
if(args.length==2){
           
new Thread(new EmplyeeJob(args[0],args[1])).start();
       
}
       
   
}

}


8、打成jar,只需要打包对应的源代码即可,上传到/opt/mapred/job/2 目录下面 join1.jar

9、/opt/mapred/job/2 下创建文件source.txt 并把需要分析的文本数据copy到该文件中

10、执行 hadoop fs -put source.txt /user/root/data/2/source.txt 将文件存放在hdfs中

11、hadoop jar join1.jar com.wy.hadoop.join.one.JobMain /user/root/data/2/source.txt /user/root/output/2

12、查看结果
    好,这样就完成了执行操作,然后看看我们得到的结果如何.从hadoop中取出结果文件.hadoop fs -get /user/root/output/2/* ./

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值