如何在java中为MapReducer作业的hadoop输入自定义选择列读取

如何在java中为MapReducer作业的hadoop输入自定义选择列读取,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,Hadoop新手,我正在尝试理解Hadoop如何读取文件输入:我能够使用下面的代码从2列(键/值)输入文件运行Hadoop作业: 但是如果我有5列,并且我想要的(键/值)是A&E(而不是A&B),那么我需要准确修改哪个函数呢 public class InverterCounter extends Configured implements Tool { public static class MapClass extends MapReduceBase implem

Hadoop新手,我正在尝试理解Hadoop如何读取文件输入:我能够使用下面的代码从2列(键/值)输入文件运行Hadoop作业:

但是如果我有5列,并且我想要的(键/值)是A&E(而不是A&B),那么我需要准确修改哪个函数呢

public class InverterCounter extends Configured implements Tool {

    public static class MapClass extends MapReduceBase
        implements Mapper<Text, Text, Text, Text> {

        public void map(Text key, Text value,
                        OutputCollector<Text, Text> output,
                        Reporter reporter) throws IOException {

            output.collect(value, key);
        }
    }   
    public static class Reduce extends MapReduceBase
        implements Reducer<Text, Text, Text, IntWritable> {

        public void reduce(Text key, Iterator<Text> values,
                           OutputCollector<Text, IntWritable> output,
                           Reporter reporter) throws IOException {

            int count = 0;
            while (values.hasNext()) {
                values.next();
                count++;
            }
            output.collect(key, new IntWritable(count));
        }
    }   
    public int run(String[] args) throws Exception {
        Configuration conf = getConf();      
        JobConf job = new JobConf(conf, InverterCounter.class);    
        Path in = new Path(args[0]);
        Path out = new Path(args[1]);
        FileInputFormat.setInputPaths(job, in);
        FileOutputFormat.setOutputPath(job, out);

        job.setJobName("InverterCounter");
        job.setMapperClass(MapClass.class);
        job.setReducerClass(Reduce.class);   
        job.setInputFormat(KeyValueTextInputFormat.class);
        job.setOutputFormat(TextOutputFormat.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.set("key.value.separator.in.input.line", ",");       
        JobClient.runJob(job);      
        return 0;
    }  
    public static void main(String[] args) throws Exception { 
        int res = ToolRunner.run(new Configuration(), new InverterCounter(), args);       
        System.exit(res);
    }
}

公共类反相器计数器扩展配置的工具{
公共静态类MapClass扩展了MapReduceBase
实现映射器{
公共无效映射(文本键、文本值、,
输出采集器输出,
(记者)抛出IOException{
输出。收集(值、键);
}
}   
公共静态类Reduce扩展了MapReduceBase
机具减速器{
public void reduce(文本键、迭代器值、,
输出采集器输出,
(记者)抛出IOException{
整数计数=0;
while(values.hasNext()){
value.next();
计数++;
}
collect(key,newintwriteable(count));
}
}   
公共int运行(字符串[]args)引发异常{
配置conf=getConf();
JobConf job=newjobconf(conf,InverterCounter.class);
路径输入=新路径(args[0]);
路径输出=新路径(args[1]);
setInputPath(作业,在中);
setOutputPath(作业,输出);
job.setJobName(“逆变器计数器”);
job.setMapperClass(MapClass.class);
job.setReducerClass(Reduce.class);
job.setInputFormat(KeyValueTextInputFormat.class);
setOutputFormat(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.set(“key.value.separator.in.input.line”、“,”);
JobClient.runJob(作业);
返回0;
}  
公共静态void main(字符串[]args)引发异常{
int res=ToolRunner.run(新配置(),新反相器计数器(),参数);
系统退出(res);
}
}
任何建议都将不胜感激,我正在尝试更改job.set(“key.value.separator.in.input.line”、“,”)和作业.setInputFormat(KeyValueTextInputFormat.class)运气不佳,仍然无法解决这个问题


谢谢

KeyValueTextInputFormat
假设键位于每行的开头,因此它不适用于6列数据集

相反,您可以使用和提取密钥,并自行确定其价值。我假设行中的所有值都用逗号分隔(数据中没有逗号,这是另一回事)

使用
TextInputFormat
可以在
值中接收整行,并在
键中接收该行在文件中的位置。我们不需要这个职位,所以我们会忽略它。使用单个
文本中的整行
,我们可以将其转换为
字符串
,用逗号将其拆分,并导出要发出的键和值:

public class InverterCounter extends Configured implements Tool {

    public static class MapClass extends MapReduceBase
        implements Mapper<Text, Text, Text, Text> {

        public void map(Text key, Text value,
                        OutputCollector<Text, Text> output,
                        Reporter reporter) throws IOException {

            String[] lineFields = value.toString().split(",");
            Text outputKey = new Text(lineFields[0] + "," + lineFields[4]);
            Text outputValue = new Text(lineFields[1] + "," + lineFields[2] + "," +
                                        lineFields[3] + "," + lineFields[5]);

            output.collect(outputKey, outputValue);
        }
    }   
    public static class Reduce extends MapReduceBase
        implements Reducer<Text, Text, Text, IntWritable> {

        public void reduce(Text key, Iterator<Text> values,
                           OutputCollector<Text, IntWritable> output,
                           Reporter reporter) throws IOException {

            int count = 0;
            while (values.hasNext()) {
                values.next();
                count++;
            }
            output.collect(key, new IntWritable(count));
        }
    }   
    public int run(String[] args) throws Exception {
        Configuration conf = getConf();      
        JobConf job = new JobConf(conf, InverterCounter.class);    
        Path in = new Path(args[0]);
        Path out = new Path(args[1]);
        FileInputFormat.setInputPaths(job, in);
        FileOutputFormat.setOutputPath(job, out);

        job.setJobName("InverterCounter");
        job.setMapperClass(MapClass.class);
        job.setReducerClass(Reduce.class);   
        job.setInputFormat(TextInputFormat.class);
        job.setOutputFormat(TextOutputFormat.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        JobClient.runJob(job);
        return 0;
    }  
    public static void main(String[] args) throws Exception { 
        int res = ToolRunner.run(new Configuration(), new InverterCounter(), args);       
        System.exit(res);
    }
}
公共类反相器计数器扩展配置的工具{
公共静态类MapClass扩展了MapReduceBase
实现映射器{
公共无效映射(文本键、文本值、,
输出采集器输出,
(记者)抛出IOException{
String[]lineFields=value.toString().split(“,”);
文本输出键=新文本(行字段[0]+“,“+行字段[4]);
文本输出值=新文本(行字段[1]+”,“+行字段[2]+”,”+
线域[3]+“,“+线域[5]);
收集(outputKey,outputValue);
}
}   
公共静态类Reduce扩展了MapReduceBase
机具减速器{
public void reduce(文本键、迭代器值、,
输出采集器输出,
(记者)抛出IOException{
整数计数=0;
while(values.hasNext()){
value.next();
计数++;
}
collect(key,newintwriteable(count));
}
}   
公共int运行(字符串[]args)引发异常{
配置conf=getConf();
JobConf job=newjobconf(conf,InverterCounter.class);
路径输入=新路径(args[0]);
路径输出=新路径(args[1]);
setInputPath(作业,在中);
setOutputPath(作业,输出);
job.setJobName(“逆变器计数器”);
job.setMapperClass(MapClass.class);
job.setReducerClass(Reduce.class);
setInputFormat(TextInputFormat.class);
setOutputFormat(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
JobClient.runJob(作业);
返回0;
}  
公共静态void main(字符串[]args)引发异常{
int res=ToolRunner.run(新配置(),新反相器计数器(),参数);
系统退出(res);
}
}

我还没有机会测试这个,所以可能会有小错误。您可能希望重命名该类,因为它不再反转任何内容。最后,该值已发送到reducer,但未被使用,因此您可以轻松地发送一个值。

Hi,@Jeremy Beard当您说change NullWriteable时,我在哪里更改它?我运行了代码并得到了以下错误:错误:java.lang.ClassCastException:org.apache.hadoop.io.LongWritable无法强制转换为org.apache.hadoop.io.Text" ... 我没有看到LongWritable,但是我可以看到IntWritable=>这就是我没有真正了解的。好吧,我链接到了错误的TextInputFormat。确保使用
org.apache.hadoop.mapred.TextInputFormat