使用mapreduce

时间:2016-07-08 18:27:51

标签: hadoop mapreduce hadoop2

假设我在HDFS中有以下文件

EmpId,EmpName,Dept,Salary,

121,raj,Dept1,8000
122,Kiran,Dept2,6000
123,John,Dept3,9000

使用mapreduce我想只得到员工的最高工资和他的名字

我能够获得最高工资但却无法获得名称..我只能通过将地图类中的空键和减速器类中的Math.max()保持为最高工资,以便能够获得只获得最高工资。当我将密钥保留为emp名称时,它会显示所有独特员工的工资。

我的Mapreduce代码

File : test.csv

121,raj,Dept1,8000

122,Kiran,Dept2,6000

123,John,Dept3,9000

public static class MyMap extends Mapper<LongWritable,Text,Text,IntWritable>    
 {  
  public void map(LongWritable k,Text v, Context con)throws IOException, InterruptedException  
  {  
   String line = v.toString();  
   String[] w=line.split(",");  
   int sal=Integer.parseInt(w[3]);  
   con.write(new Text("Raj"), new IntWritable(sal));  
   }  
 }

 public static class MyRed extends Reducer<Text,IntWritable,IntWritable,Text>  
 {  
  public void reduce(Text k, Iterable<IntWritable> vlist, Context con)
  throws IOException , InterruptedException  
     {  
      int max=0;  
      for(IntWritable v:vlist)  
   {
      max=Math.max(max, v.get());   
   }  

   con.write(new IntWritable(max), new Text());  
  }

输出:
9000
在这里,我需要输出为:9000 john

请发布您的代码。

3 个答案:

答案 0 :(得分:1)

map阶段,保存薪水最高的条目,并在cleanup期间将其写入上下文。这导致每个映射器只有一个输出,这是映射器具有最高工资的那些映射器。输出条目时,您只需输出整个文本行。在 reduce阶段,您再次拆分文本行并确定最大值。已发送文本行的工资 - 由于每个映射器只发送一个项目而没有那么多。

Here是Java中用于根据其声誉确定前10位用户的示例。你应该能够从中得到这个想法。

顺便说一句:您要求代码但没有提及哪种语言,也没有显示您之前的任何尝试,因此我只想指出上述示例。

答案 1 :(得分:0)

请尝试以下代码。你会得到结果。

public static class MyMap extends Mapper<LongWritable,Text,Text,Text>    
 {  
  public void map(LongWritable k,Text v, Context con)throws IOException, InterruptedException  
  {  
   String line = v.toString();  
   String[] w=line.split(",");  
   int sal=Integer.parseInt(w[3]);  
   string name=Integer.parseInt(w[1]);
   con.write(new Text(name), new Text(name+","+sal));  
   }  
 } 

 public static class MyRed extends Reducer<Text,Text,IntWritable,Text>  
 {  
  public void reduce(Text k, Iterable<Text> vlist, Context con)
  throws IOException , InterruptedException  
     {  
      int max=0;  
      for(Text v:vlist)  
   {
        String line = v.toString();  
        String[] w=line.split(",");  
        int sal=Integer.parseInt(w[1]); 
        max=Math.max(max, sal);
   }  
   con.write(new IntWritable(max), k);  
  }

 }

答案 2 :(得分:0)

您必须传递来自映射器的值,例如{raj,8000 kiran,6000 john,9000},因此键将保持不变,在下面的代码中您可以检查如何完成操作,

 public class MyMap extends Mapper<LongWritable,Text,Text,Text>    
   {  
     public void map(LongWritable k,Text v, Mapper<LongWritable,Text,Text,Text>.Context 
     con)throws IOException, InterruptedException  
   {  
     String line = v.toString();  
     String[] w=line.split(","); 
     String name = w[1] ; 
    int sal=Integer.parseInt(w[3]);  
    String map_op = name+","+sal ; 
    con.write(new Text("ds"), new Text(map_op)); 
    //ds {raj,8000 kiran,6000 john,9000}

    }  
   }

经过混排和排序后的“ // ds {raj,8000 kiran,6000 john,9000}”

这将是结果,这里我们将ds作为键传递,

现在让我们看一下reducer方法

    public class MyRed extends Reducer<Text,Text,IntWritable,Text>  
{  

      //ds {raj,8000 kiran,6000 john,9000}

 public void reduce(Text k, Iterable<Text> vlist, Reducer<Text,Text,IntWritable,Text>.Context con)
 throws IOException , InterruptedException  
    {  
     int max=0;  
     String name = k.toString() ;

     for(Text v: vlist)  
  {

         int salary = Integer.parseInt(v.toString().split(",")[1]) ;
         max=Math.max(max, salary); 

         if(salary == max)
        {
            name = v.toString().split(",")[0] ;
        }
  }  

  con.write(new IntWritable(max), new Text(name));  
 }
}

// 9000约翰:-该o / p将由减速器产生