Java Hadoop NtripleMapper(apache.jena)工作不正常,映射输入记录=0

Java Hadoop NtripleMapper(apache.jena)工作不正常,映射输入记录=0,java,hadoop,mapreduce,rdf,jena,Java,Hadoop,Mapreduce,Rdf,Jena,我正在研究PageRank算法的实现,该算法使用Hadoop、MapReduce和RDF三元组作为源代码 到目前为止,代码非常简单,主类中只有一个作业,其次是mapper和reducer。输入文件是一个.nt文件,其中充满了rdf三元组,例如: <http://dbpedia.org/resource/Anarchism> <http://dbpedia.org/ontology/wikiPageWikiLink> <http://dbpedia.org/resou

我正在研究PageRank算法的实现,该算法使用Hadoop、MapReduce和RDF三元组作为源代码

到目前为止,代码非常简单,主类中只有一个作业,其次是mapper和reducer。输入文件是一个.nt文件,其中充满了rdf三元组,例如:

<http://dbpedia.org/resource/Anarchism> <http://dbpedia.org/ontology/wikiPageWikiLink> <http://dbpedia.org/resource/Red_Army> .
输入文件长约1500行,执行大约需要1分钟,但会生成空输出(包括_successsic!)。显然,映射器工作不正常,因为在日志中我可以看到

 Map-Reduce Framework
         Map input records=0
         Map output records=0
         Map output bytes=0
今天我们花了8个小时来修改这段代码,但没有得到一个输出。因此,我请求你的帮助,同事们

我将在代码下面粘贴更多来自作业执行的日志,这可能会有所帮助。我还注意到,在作业执行期间,每当作业运行映射器时,hadoop namenode都会抛出

15/04/27 21:15:59 INFO ipc.Server: Socket Reader #1 for port 9000: readAndProcess from client 127.0.0.1 threw exception [java.io.IOException: An existing connection was forcibly closed by the remote host] 
 at sun.nio.ch.SocketDispatcher.read0(Native Method)
 at sun.nio.ch.SocketDispatcher.read(Unknown Source)
 at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
 at sun.nio.ch.IOUtil.read(Unknown Source)
 at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
 at org.apache.hadoop.ipc.Server.channelRead(Server.java:2502)
 at org.apache.hadoop.ipc.Server.access$2800(Server.java:124)
 at org.apache.hadoop.ipc.Server$Connection.readAndProcess(Server.java:1410)
 at org.apache.hadoop.ipc.Server$Listener.doRead(Server.java:708)
 at org.apache.hadoop.ipc.Server$Listener$Reader.doRunLoop(Server.java:582)
 at org.apache.hadoop.ipc.Server$Listener$Reader.run(Server.java:553)
根据一些文章,我发现它不会毁掉我的制图器,但它确实看起来可疑,我不知道为什么会发生

主要类别:

public class PageRankHadoop {

public static void main(String[] args) {
    try {
        Configuration conf = new Configuration();

        Job job = new Job(conf, "Page Rank RDF Hadoop");
        job.setJarByClass(PageRankHadoop.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.setMapperClass(NTriplesMapper.class);
        job.setReducerClass(NTriplesReducer.class);
        job.setInputFormatClass(NTriplesInputFormat.class);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.waitForCompletion(true);
    } catch (IOException | IllegalStateException | IllegalArgumentException | InterruptedException | ClassNotFoundException e) {
        System.err.println("Error! " + e.getMessage());
        e.printStackTrace(System.err);
    }

}
}

Mapper:
公共类NtripleMapper扩展了Mapper{
@凌驾
受保护的void映射(LongWritable键、TripleWritable值、上下文){
试一试{
write(键,新文本(value.get().getObject().getURI());
}捕获(IOException | InterruptedException ex){
System.err.println(“映射器错误:+ex.getMessage());
例如printStackTrace(System.err);
}
}
}
减速器:
公共类NTriplesReducer扩展了Reducer{
@凌驾
受保护的void reduce(LongWritable键、Iterable值、上下文){
字符串pageRankList=“1.0”;
用于(文本值:值){
pageRankList+=”,“+value.toString();
}
试一试{
write(新文本(key.toString()),新文本(pageRankList));
}捕获(IOException | InterruptedException ex){
System.err.println(“减速器错误:+ex.getMessage());
例如printStackTrace(System.err);
}
}
}
Shell作业执行日志: 来自hadoop\logs\userlogs的系统日志:


编辑,在代码中添加日志,没有引发异常。还尝试在linux下的hadoop 2.6.0上运行此代码,结果与在windows下的hadoop 2.3.0上运行此代码的结果相同。您的代码可能存在许多问题,我将尝试强调这些问题,但不清楚是哪一个问题导致了此问题

吞咽错误 第一个明显的问题是,您的代码会吞咽错误:

catch (IOException | IllegalStateException | IllegalArgumentException | InterruptedException | ClassNotFoundException e) {
    }
这意味着您的作业抛出的任何错误都将被静默抑制。至少您应该将错误转储到控制台,例如

catch (Throwable e) {
  System.err.println(e.getMessage());
  e.printStackTrace(System.err);
}
这是我要更改的第一件事,如果您随后开始看到错误消息,这将为您提供一个指向问题实际原因的指针

类型签名 其次,您直接在
Mapper
Reducer
中使用
Triple
类型。
Triple
类型是标准的Java对象,不能作为Hadoop
可写类型使用

要在Hadoop上使用RDF数据,您需要使用库(至少在代码的一部分中是这样做的)和
TripleWritable
类型,因此不清楚Hadoop为什么让您的代码编译/运行

文件读取问题 一个可能的问题是,您可能需要显式指定要递归搜索输入路径。每次尝试在设置作业的输入路径之前添加以下内容:

FileInputFormat.setInputDirRecursive(true);
Hadoop版本不匹配
您使用的是Hadoop 2.3.0,而Elephas是为2.6.0构建的-我不认为Elephas使用了任何不向后兼容的API,但是如果所有其他方面都失败了,您可以尝试根据Hadoop版本不匹配的文档,根据Hadoop版本自己构建库,或者更确切地说,Jena版本是问题所在。其中一个依赖项太旧了,我没有给出任何相关信息,但使用最新版本解决了问题。

感谢您的输入,我将在下班回家后测试这些更改。至于吞咽错误部分,我在那里有专门的记录器,但我不确定我必须放入hadoop中的额外记录器(jar)是否没有引起问题,我将在那里放置简单的serr。至于类型签名,我将更改它,它可能会导致问题。至于文件读取问题,在shell作业执行日志中,我们可以读取HDFS:Number of bytes Read=4641,这是正确的,因为文件大约有5kB大。至于Hadoop版本,我今天将在linux下的2.6.0上检查它。关于文件读取的观点很好,读取日志的错误部分对不起!好的,我在linux下hadoop 2.6.0上试过,绝对没有区别,仍然是0输出。我还在catch中添加了记录器,但并没有抛出异常(记录器工作,我使用无效的输出路径对其进行了测试,然后它正确地抛出了异常)。这就给我们留下了类型签名,我已经更改了Map方法的参数以匹配输入格式,也就是说,但它没有产生任何效果。感觉我好像死胡同了,需要更多的帮助。Hadoop版本不匹配,或者更确切地说是Jena版本的问题。其中一个依赖项太旧了,我确实给出了它的任何迹象,但使用最新版本修复了这个问题。
Mapper:

   public class NTriplesMapper extends Mapper<LongWritable, TripleWritable, LongWritable, Text> {

    @Override
    protected void map(LongWritable key, TripleWritable value, Context context) {
        try {
            context.write(key, new Text(value.get().getObject().getURI()));
        } catch (IOException | InterruptedException ex) {
            System.err.println("Mapper error: " + ex.getMessage());
            ex.printStackTrace(System.err);
        }
    }
}
Reducer:

   public class NTriplesReducer extends Reducer<LongWritable, Text, Text, Text> {

    @Override
    protected void reduce(LongWritable key, Iterable<Text> values, Context context) {
        String pageRankList = "1.0";
        for (Text value : values) {
            pageRankList += "," + value.toString();
        }
        try {
            context.write(new Text(key.toString()), new Text(pageRankList));
        } catch (IOException | InterruptedException ex) {
            System.err.println("Reducer error: " + ex.getMessage());
            ex.printStackTrace(System.err);
        }
    }
}
catch (IOException | IllegalStateException | IllegalArgumentException | InterruptedException | ClassNotFoundException e) {
    }
catch (Throwable e) {
  System.err.println(e.getMessage());
  e.printStackTrace(System.err);
}
FileInputFormat.setInputDirRecursive(true);