2

私の学士論文の一部は、.nt ファイル (タートル形式) を neo4j データベースにロードすることです。それを読み込んで可能な実装を探した後、OpenRDF による SailRepositoryConnection を使用した実装が必要なように機能することがわかりました。しかし、OOM/GC で重大な問題が発生しました。私が使用するライブラリ: - Blueprints 2.5 - OpenRDF Sesame 2.7.8 - Neo4j 2.0.3

私が使用するシステム: - Fedora 19 64 ビット - 4 Gb RAM - Java バージョン 1.7.0_51

私のコードは次のとおりです。

public void loadFile() throws SailException {
        //load file
        Neo4j2Graph neo4jGraph = new Neo4j2Graph(this.DB_DIRECTORY);
        BatchGraph<TransactionalGraph> neo = new BatchGraph<TransactionalGraph>(neo4jGraph, VertexIDType.NUMBER, 1);

    GraphSail sail = new GraphSail( neo4jGraph );
    sail.initialize();

    SailRepositoryConnection connection;
    try { 
        connection = new SailRepository( sail ).getConnection();

        URL url = f.toURI().toURL(); // getClass().getResource( this.f.getCanonicalPath() );
        // System.out.println( "Loading " + url + ": " );

        connection.add(url, null , RDFFormat.NTRIPLES);

        connection.commit();
        connection.close();
    } catch ( Exception e ) {
        e.printStackTrace(System.out);
    }

    // System.out.print( "Done." );

    sail.shutDown();
    neo4jGraph.shutdown();
    neo.shutdown();
}

非常に小さな .nt ファイル (4800 トリプルなど) では問題なく動作します。しかし、180 万個のトリプルを含む .nt ファイルを読み込もうとすると、次のエラーが発生します。

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at org.apache.lucene.search.TermQuery$TermWeight.<init>(TermQuery.java:53)
    at org.apache.lucene.search.TermQuery.createWeight(TermQuery.java:199)
    at org.apache.lucene.search.Searcher.createNormalizedWeight(Searcher.java:168)
    at org.apache.lucene.search.IndexSearcher.createNormalizedWeight(IndexSearcher.java:664)
    at org.apache.lucene.search.Query.weight(Query.java:103)
    at org.neo4j.index.impl.lucene.Hits.<init>(Hits.java:101)
    at org.neo4j.index.impl.lucene.LuceneIndex.search(LuceneIndex.java:427)
    at org.neo4j.index.impl.lucene.LuceneIndex.query(LuceneIndex.java:314)
    at org.neo4j.index.impl.lucene.LuceneIndex.get(LuceneIndex.java:229)
    at org.neo4j.kernel.impl.coreapi.AbstractAutoIndexerImpl$IndexWrapper.get(AbstractAutoIndexerImpl.java:176)
    at com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Graph.getVertices(Neo4j2Graph.java:369)
    at com.tinkerpop.blueprints.oupls.sail.GraphSail$DataStore.findVertex(GraphSail.java:297)
    at com.tinkerpop.blueprints.oupls.sail.GraphSailConnection.getOrCreateVertex(GraphSailConnection.java:241)
    at com.tinkerpop.blueprints.oupls.sail.GraphSailConnection.addStatementInternal(GraphSailConnection.java:208)
    at com.tinkerpop.blueprints.oupls.sail.GraphSailConnection.addStatementInternal(GraphSailConnection.java:165)
    at org.openrdf.sail.helpers.SailConnectionBase.addStatement(SailConnectionBase.java:471)
    at org.openrdf.repository.sail.SailRepositoryConnection.addWithoutCommit(SailRepositoryConnection.java:281)
    at org.openrdf.repository.base.RepositoryConnectionBase.add(RepositoryConnectionBase.java:469)
    at org.openrdf.repository.util.RDFInserter.handleStatement(RDFInserter.java:207)
    at org.openrdf.rio.ntriples.NTriplesParser.parseTriple(NTriplesParser.java:319)
    at org.openrdf.rio.ntriples.NTriplesParser.parse(NTriplesParser.java:193)
    at org.openrdf.rio.ntriples.NTriplesParser.parse(NTriplesParser.java:132)
    at org.openrdf.repository.util.RDFLoader.loadInputStreamOrReader(RDFLoader.java:325)
[Full GC 963967K->963934K(963968K), 5.8010570 secs]
    at org.openrdf.repository.util.RDFLoader.load(RDFLoader.java:222)
    at org.openrdf.repository.util.RDFLoader.load(RDFLoader.java:180)
    at org.openrdf.repository.base.RepositoryConnectionBase.add(RepositoryConnectionBase.java:253)
    at src4neo2graph.QnL2.loadFile(QnL2.java:181)
    at main.Main.main(Main.java:52)

また、別のシステムで 4Gb で実行しようとしましたが、同じエラーが発生しました。そこで、ガベージコレクションにいくつかのコマンドを使用してみました:(特にその順序ではありませんが、一度にすべて試しました)

Xms2G -Xmx2G -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:MaxHeapFreeRatio=95

しかし、それも役に立ちませんでした。

私はたくさん検索しましたが、これは.ntファイルをNeo4j DBにロードするために誰もが使用している実装のようです。私が書いたように、少数のトリプルで問題なく動作します. だから基本的に:私の実装に何か問題がありますか?より良いものはありますか?これを機能させるにはどうすればよいですか (追加の RAM を購入する以外に (別のシステムでさらにテストしたと言ったように))、これを機能させるにはどうすればよいですか?

前もって感謝します。

4

3 に答える 3

5

実際にファイルをチャンクに分割する必要はありません。ステートメントが追加されるたびに数え、n番目のステートメントごとに commit() ます。blueprints-graph-sail には、これを行う便利なクラスSailLoader ( source ) があります。

public void loadFile() throws Exception {
    File f = new File("/tmp/sp2bench-1000000.nt.gz");

    Neo4j2Graph neo4jGraph = new Neo4j2Graph(this.DB_DIRECTORY);
    try {
        GraphSail sail = new GraphSail(neo4jGraph);
        sail.initialize();

        try {
            SailLoader loader = new SailLoader(sail);
            loader.setBufferSize(1000);  // this is the default
            loader.setVerbose(true);
            loader.load(f);
        } finally {
            sail.shutDown();
        }
    } finally {
        neo4jGraph.shutdown();
    }
}
于 2014-05-31T13:07:59.050 に答える
0

解決策はわかりましたか?私も同じ問題を抱えてる。ファイルをチャンクに分割してロードしましたか? それとも何か?ファイルをチャンクに分割した場合、クエリは以前と同じように機能しますか?

あなたの質問に答えるために、

Neo4j を純粋なトリプル ストアとして使用する予定がない場合。タートル ファイルを非常に高速にロードし、cypher を使用してクエリできるグラフを作成する別の方法を次に示します。

http://michaelbloggs.blogspot.de/2013/05/importing-ttl-turtle-ontologies-in-neo4j.html

それが役に立てば幸い!

于 2014-05-30T18:55:53.240 に答える
0

ティンカーポップが内部でどのように機能するかは確かですが、すべてが単一のトランザクションで行われると思います。Neo4j では、トランザクションは最初にメモリ内に構築され、tx が完了すると永続化され、使用されたメモリは次の gc で解放されます。大規模なトランザクションがある場合は、適切な量の RAM が必要です。

tinkerpop 内でトランザクション サイズを制御する簡単な方法がない場合は、入力ファイルを小さなチャンクに分割して 1 つずつインポートし.commit()、各チャックの後に必ず呼び出すことを検討してください。

于 2014-05-28T07:03:21.310 に答える