5

i want to store some data in my neo4j database. i use spring-data-neo4j for that.

my code is like the follow:

    for (int i = 0; i < newRisks.size(); i++) {
        myRepository.save(newRisks.get(i));
        System.out.println("saved " + newRisks.get(i).name);
    }

私の newRisks-array には、約 60000 個のオブジェクトと 60000 個のエッジが含まれています。すべてのノードとエッジには 1 つのプロパティがあります。このループの長さは約 15 ~ 20 分ですが、これは正常ですか? Java VisualVM を使用していくつかのボトルネックを検索しましたが、平均 CPU 使用率は 10 ~ 25% (4 コアの場合) であり、ヒープは半分以下でした。

この操作を後押しするオプションはありますか?


編集:追加は、myRepository.save(newRisks.get(i));最初の出力が来る数分前に、jvm の最初の呼び出しで assleep fpr に落ちることです

2番目の編集:

クラスリスク:

@NodeEntity
public class Risk {
    //...
    @Indexed
    public String name;

    @RelatedTo(type = "CHILD", direction = Direction.OUTGOING)
    Set<Risk> risk = new HashSet<Risk>();

    public void addChild(Risk child) {
        risk.add(child);
    }

    //...
}

リスクの作成:

@Autowired
private Repository myRepository;

@Transactional
public Collection<Risk> makeSomeRisks() {

    ArrayList<Risk> newRisks = new ArrayList<Risk>();

    newRisks.add(new Risk("Root"));

    for (int i = 0; i < 60000; i++) {
        Risk risk = new Risk("risk " + (i + 1));
        newRisks.get(0).addChild(risk);
        newRisks.add(risk);
    }

    for (int i = 0; i < newRisks.size(); i++) {
        myRepository.save(newRisks.get(i));
    }

    return newRisks;
}
4

4 に答える 4

5

私は解決策を見つけたと思います:

nativ neo4jjavaAPIを使用して同じ挿入を試しました。

GraphDatabaseService graphDb;
Node firstNode;
Node secondNode;
Relationship relationship;

graphDb = new EmbeddedGraphDatabase(DB_PATH);
Transaction tx = graphDb.beginTx();

try {
    firstNode = graphDb.createNode();
    firstNode.setProperty( "name", "Root" );

    for (int i = 0; i < 60000; i++) {
        secondNode = graphDb.createNode();
        secondNode.setProperty( "name", "risk " + (i+1));

        relationship = firstNode.createRelationshipTo( secondNode, RelTypes.CHILD );
    }
    tx.success();
}
finally {
    tx.finish();
    graphDb.shutdown();
}

結果:いくつかのscondsの後、データベースはリスクでいっぱいになります。

たぶん、反射はspring-data-neo4jでこのルーチンを遅くします。@Michael Hungerは、彼の著書GoodRelationshipsで、そのようなことを言っています。そのヒントに感謝します。

于 2012-03-06T15:12:34.313 に答える
5

ここでの問題は、それを目的としていないAPIを使用して一括挿入を実行していることです。

リスクと60kの子を作成し、最初にルートを保存します。これにより、同時に60kの子も保持されます(そして関係が作成されます)。そのため、最初の保存には非常に時間がかかります。そして、あなたは再び子供たちを救います。

SDNでそれをスピードアップするためのいくつかの解決策があります。

  1. 一括挿入にコレクションアプローチを使用せず、両方の参加者を永続化し、template.createRelationshipBetween(root、child、 "CHILD"、false);を使用します。

  2. 最初に子を永続化し、次に永続化されたすべての子をルートオブジェクトに追加し、それを永続化します

  3. 行ったように、Neo4j-Core APIを使用しますが、template.postEntityCreation(node、Risk.class)を呼び出して、SDNを介してエンティティにアクセスできるようにします。次に、エンティティに独自のインデックスを作成する必要があります(db.index.forNodes( "Risk")。add(node、 "name"、name);)(または、neo4j core-api自動インデックスを使用しますが、そうではありません。 SDNと互換性があります)。

  4. コアAPIまたはSDNに関係なく、最高のパフォーマンスを得るには、約10〜20kノード/relのtxサイズを使用する必要があります

于 2012-03-11T22:42:56.403 に答える
1

データベース (Java 以外) への挿入には同じ遅延がありますか、それとも春のデータだけの問題ですか?

于 2012-03-05T15:46:44.127 に答える
1

OPと同じ問題に直面しました。私の場合、Neo4j の使用法をリモート サーバーモードからembeddedに変更することが本当に役に立ちました。組み込み SDN の使用例は、こちら にあります

于 2016-04-07T10:45:00.843 に答える