Hadoop MapReduce如何在HDFS中仅存储值

5

我正在使用这个工具来删除重复行。

public class DLines
 {
   public static class TokenCounterMapper extends Mapper<Object, Text, Text, IntWritable>
    {
    private final static IntWritable one = new IntWritable(1);
      private Text word = new Text();
      @Override
      public void map(Object key, Text value, Context context) throws IOException, InterruptedException
       {
           String line=value.toString();
           //int hash_code=line.hashCode();
           context.write(value, one);
       }
   }

public static class TokenCounterReducer extends Reducer<Text, IntWritable, Text, IntWritable> 
 {
        @Override
    public void reduce(Text key, Iterable<IntWritable> values, Context context)throws IOException, InterruptedException 
     {
 public void reduce(Text key, Iterable<IntWritable> values, Context context)throws IOException, InterruptedException 
     {
       int sum = 0;
       for (IntWritable value : values) 
       {   
           sum += value.get();        
       }
       if (sum<2)
           {
             context.write(key,new IntWritable(sum));
           }
      }
      }

我需要将只有Key的数据存储在HDFS中。

2个回答

4
如果您的reducer不需要返回值,只需使用NullWritable即可。
您可以简单地使用context.write(key, NullWritable.get());
在您的driver中,您也可以设置。
 job.setMapOutputKeyClass(Text.class);
 job.setMapOutputValueClass(IntWritable.class);

&

 job.setOutputKeyClass(Text.class);
 job.setOutputValueClass(NullWritable.class);

当使用上述代码以及组合器时,进行任何代码更改都会导致出错。 - Abhinay

0
你可以使用 NullWritable 类来实现。
public class DLines
 {
   public static class TokenCounterMapper extends Mapper<Object, Text, Text, IntWritable>
    {
    private final static IntWritable one = new IntWritable(1);
      private Text word = new Text();
      @Override
      public void map(Object key, Text value, Context context) throws IOException, InterruptedException
       {
           String line=value.toString();
           context.write(value, one);
       }
   }

public static class TokenCounterReducer extends Reducer<Text, IntWritable, Text, NullWritable> 
 {
   NullWritable out = NullWritable.get();
        @Override
    public void reduce(Text key, Iterable<IntWritable> values, Context context)throws IOException, InterruptedException 
       {
       int sum = 0;
       for (IntWritable value : values) 
       {   
           sum += value.get();        
       }
       if (sum<2)
           {
             context.write(key,out);
           }
      }
      }

驱动程序代码

job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);

希望这个回答解决了你的问题。

我尝试了同样的方法,它可以正常工作。但是当我使用组合器时,我会收到以下错误信息: java.io.IOException: wrong value class: class org.apache.hadoop.io.NullWritable is not class org.apache.hadoop.io.IntWritable - Abhinay
@Abhinay:在这种情况下,您不能使用合并器。合并器是迷你减速器,其操作是可交换和可结合的,并且合并器的签名应与减速器匹配。如果合并器签名为“<Text,IntWritable,Text,NullWritable>”,则会出现错误,因为减速器输入键和值为--Text和IntWritable,但合并器的输出键和值类为Text,NullWritable。 - USB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接