我正试图遵循一个网站上的hadoop教程。我正在尝试用java实现它。提供的文件是包含有关论坛的数据的文件。我想解析那个文件并使用数据。
设置配置的代码如下:
public class ForumAnalyser extends Configured implements Tool{
public static void main(String[] args) {
int exitCode = 0;
try {
exitCode = ToolRunner.run(new ForumAnalyser(), args);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
System.exit(exitCode);
}
}
@Override
public int run(String[] args) throws Exception {
JobConf conf = new JobConf(ForumAnalyser.class);
setStudentHourPostJob(conf);
JobClient.runJob(conf);
return 0;
}
public static void setStudentHourPostJob(JobConf conf) {
FileInputFormat.setInputPaths(conf, new Path("input2"));
FileOutputFormat.setOutputPath(conf, new Path("output_forum_post"));
conf.setJarByClass(ForumAnalyser.class);
conf.setMapperClass(StudentHourPostMapper.class);
conf.setOutputKeyClass(LongWritable.class);
conf.setMapOutputKeyClass(LongWritable.class);
conf.setReducerClass(StudentHourPostReducer.class);
conf.setOutputValueClass(IntWritable.class);
conf.setMapOutputValueClass(IntWritable.class);
}
}
文件中的每条记录都用“\n”分隔。因此,在mapper类中,每个记录基本上都是正确返回的。每条记录中的每一列都用制表符隔开。问题出现在特定的“posts”列中。此列包含由人编写的“posts”,因此也包含“\n”。因此Map程序错误地将“posts”列下的某一行作为新记录读取。另外,“posts”列在文件中用双引号括起来。我的问题是:1。如何让Map器正确区分每条记录?我能告诉它按标签阅读每一列吗(我知道每条记录有多少列?
事先谢谢你的帮助。
1条答案
按热度按时间f45qwnt81#
默认情况下,mapreduce使用
TextInputFormat
,其中每条记录都是一行输入(假定每条记录都由新行(“\n”)分隔)。为了达到你的要求,你需要写你自己的
InputFormat
以及RecordReader
班级。例如,在mahout中,有一个XmlInputFormat
用于将整个xml文件作为一条记录读取。请在此处检查代码:https://github.com/apache/mahout/blob/master/integration/src/main/java/org/apache/mahout/text/wikipedia/xmlinputformat.java我把密码当成
XmlInputFormat
并对其进行了修改以达到您的要求。这是代码(我称之为MultiLineInputFormat
以及MultiLineRecordReader
):逻辑:
我假设包含新行(“\n”)的字段用双引号(“)分隔。
记录读取逻辑处于
readUntilEnd()
方法。在这个方法中,如果出现一个新行,并且我们正在读取一个字段(由双引号分隔),我们不认为它是一个记录。
为了测试这一点,我编写了一个标识Map器(它将输入按原样写入输出)。在驱动程序中,可以显式指定输入格式作为自定义输入格式。
例如,我将输入格式指定为:
代码如下:
我在下面的输入上运行了这个。输入记录与输出记录完全匹配。您可以看到每个记录中的第二个字段包含新行(“\n”),但输出中仍然返回整个记录。
e:\hadooptests\target>hadoop fs-cat/in/in8.txt
e:\hadooptests\target>hadoopfs-cat/out/*
注意:我写这段代码是为了演示。您需要处理转角情况(如果有)并优化代码(如果有优化的范围)。