hadoop处理不同输入目录文件

在写mapred任务的时候免不了要处理join。
在join中最简单的就是一对一的join。
下面通过一个小例子介绍如果在mapred中实现一对一的join。

name.txt
100 tom
101 mary
102 kate

score.txt
100 90
101 85
102 80

要得到如下的join结果
100 tom 90
101 mary 85
102 kate 80

处理思路:
mapred的输入文件为name.txt和score.txt两个,我们要通过标志区分出每条记录是来自哪个文件,所以在map的输出结果要增加文件的标志。
map的输出类似
100 name+tom
100 score+90
然后在red的过程中根据不同的前缀来区分不同记录。因为是一对一的join,所以只要将相同key的不同value连接起来后输出即可。

程序代码如下:

 package org.myorg; 
 
 import java.io.IOException; 
 import java.util.*; 
 import java.lang.String;
 
 import org.apache.hadoop.fs.Path; 
 import org.apache.hadoop.conf.*; 
 import org.apache.hadoop.io.*; 
 import org.apache.hadoop.mapred.*; 
 import org.apache.hadoop.util.*; 
 
 public class OneOnOneJoin { 
 
    public static class Map extends MapReduceBase implements Mapper<Text, Text, Text ,Text> {
   
      public void map(Text key, Text value, OutputCollector<Text , Text> output, Reporter reporter) throws IOException { 
     
       String path=((FileSplit)reporter.getInputSplit()).getPath().toString();
       Text kv = new Text();
       
       if(path.indexOf(”name.txt”)>0) {
        kv.set(”name”+”+”+value);
       } else if(path.indexOf(”score.txt”)>0) {
        kv.set(”score”+”+”+value);
       }
       
       output.collect(key,kv);
      } 
    } 

    public static class Reduce extends MapReduceBase implements Reducer<Text ,Text,  Text,Text> { 
      public void reduce(Text key, Iterator<Text> values, OutputCollector<Text,Text> output, Reporter reporter) throws IOException { 
       
 String name=”";
 String score=”";
 
        while(values.hasNext()) {
         String value = values.next().toString();
         
         if(value.startsWith(”name+”)) {
          name=value.substring(5 , value.length());  
         } else if(value.startsWith(”score+”)) {      
          score=value.substring(6 , value.length()); 
         }
        }
       
 if(!name.equals(”") && !score.equals(”")) {
  output.collect(key,new Text(name + “\t” + score));
 }
       
      } 
    } 
   
    public static void main(String[] args) throws Exception { 
      JobConf conf = new JobConf(OneOnOneJoin.class); 
      conf.setJobName(”oneononejoin”); 
 
      conf.setOutputKeyClass(Text.class); 
      conf.setOutputValueClass(Text.class); 
 
      conf.setMapperClass(Map.class); 
      conf.setReducerClass(Reduce.class); 
 
      conf.setInputFormat(KeyValueTextInputFormat.class); 
      conf.setOutputFormat(TextOutputFormat.class); 
 
      FileInputFormat.setInputPaths(conf, new Path(args[0])); 
      FileOutputFormat.setOutputPath(conf, new Path(args[1])); 
 
      JobClient.runJob(conf); 
    } 
 }  
 
编译并执行
javac -classpath ${HADOOP_HOME}/hadoop-${HADOOP_VERSION}-core.jar -d OneOnOneJoin OneOnOneJoin.java
jar -cvf OneOnOneJoin.jar -C OneOnOneJoin/ .

hadoop fs -rmr /sunwg/output
hadoop jar OneOnOneJoin.jar org.myorg.OneOnOneJoin /sunwg/input /sunwg/output  

查看结果
[hadoop@hadoop00 sunwg]$ hadoop fs -cat /sunwg/output/part-00000
100     tom     90
101     mary    85
102     kate    80

进一步考虑外连接的情况,有可能在score中没有对应的记录
比如:

name.txt
100 tom
101 mary
102 kate

score.txt
100 90
102 80

要得到如下的join结果
100 tom 90
101 mary 
102 kate 80

只要修改reduce中的最后输出结果的检验条件为

if(!name.equals(”")) {
 output.collect(key,new Text(name + “\t” + score));
}

结果
[hadoop@hadoop00 sunwg]$ hadoop fs -cat /sunwg/output/part-00000
100     tom     90
101     mary
102     kate    80

在进一步考虑全连接的情况,有可能在name中没有对应的记录
比如:
name.txt
100 tom
101 mary

score.txt
100 90
102 80

要得到如下的join结果
100 tom 90
101 mary 
102   80
只要修改reduce中的最后输出结果的检验条件为

if(!name.equals(”")) {
 output.collect(key,new Text(name + “\t” + score));
}
else if(!score.equals(”")) {
 output.collect(key,new Text(name + “\t” + score));
}

结果
[hadoop@hadoop00 sunwg]$ hadoop fs -cat /sunwg/output/part-00000
100     tom     90
101     mary
102             80


以上实现了两个文件的JOIN操作,采用相同的策略,可以对不同输入目录的文件添加相同标记,采用不同的map、reduce策略来实现对不同的目录实现不同的操作


转载地址:http://www.alidw.com/?p=1710


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值