将值写入文件而不移动到reducer

时间:2013-06-20 11:57:00

标签: hadoop mapreduce

我输入了这样的记录, 一个| 1 | Y, C | 0 | N, Ç| 1 | N, d | 2 | Y, E | 1 | Y

现在,在mapper中,我必须检查第三列的值。如果它是'Y',那么该记录必须直接写入输出文件而不将该记录移动到reducer,否则,'N'值记录必须移动到reducer进行进一步处理..

所以, 一个| 1 | Y, d | 2 | Y, E | 1 | Y 不应该去减速机但是 C | 0 | N, Ç| 1 | N 应该去reducer然后输出文件。

我该怎么做?

3 个答案:

答案 0 :(得分:2)

您可以做的是使用MultipleOutputs - click here来分隔' Y'和' N'从mappers中键入两个不同的文件。

接下来,为两个新生成的' Y'运行saparate作业。和' N'类型数据集。 对于' Y'类型将reducer的数量设置为0,因此,Reducers不能使用。并且,对于N' N'类型以你想要的方式使用reducer。

希望这有帮助。

答案 1 :(得分:1)

看看是否有效,

public class Xxxx {

    public static class MyMapper extends
            Mapper<LongWritable, Text, LongWritable, Text> {        

        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {               

            FileSystem fs = FileSystem.get(context.getConfiguration());
            Random r = new Random();                
            FileSplit split = (FileSplit)context.getInputSplit();
            String fileName = split.getPath().getName();                
            FSDataOutputStream out = fs.create(new Path(fileName + "-m-" + r.nextInt()));                               
            String parts[];
            String line = value.toString();
            String[] splits = line.split(",");
            for(String s : splits) {
                parts = s.split("\\|");
                if(parts[2].equals("Y")) {                  
                    out.writeBytes(line);
                }else {
                    context.write(key, value);
                }
            }
            out.close();
            fs.close();
        }       
    }

    public static class MyReducer extends
            Reducer<LongWritable, Text, LongWritable, Text> {
        public void reduce(LongWritable key, Iterable<Text> values,
                Context context) throws IOException, InterruptedException {
            for(Text t : values) {
            context.write(key, t);
            }
        }
    }

    /**
     * @param args
     * @throws IOException 
     * @throws InterruptedException 
     * @throws ClassNotFoundException 
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        // TODO Auto-generated method stub

        Configuration conf = new Configuration();
        conf.set("fs.default.name", "hdfs://localhost:9000");
        conf.set("mapred.job.tracker", "localhost:9001");
        Job job = new Job(conf, "Xxxx");
        job.setJarByClass(Xxxx.class);
        Path outPath = new Path("/output_path");
        job.setMapperClass(MyMapper.class);
        job.setReducerClass(MyReducer.class);
        FileInputFormat.addInputPath(job, new Path("/input.txt"));
        FileOutputFormat.setOutputPath(job, outPath);
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

答案 2 :(得分:-1)

在地图功能中,您将逐行获取输入。根据使用|拆分它作为分隔符。 (准确地使用String.split()方法) 它看起来像这样

String[] line = value.toString().split('|');

line[2]

访问此数组的第三个元素

然后,使用简单的if else语句,以N值发出输出以供进一步处理。