Frage

Ich muss eine große Anzahl von Knoten mit Beziehungen zwischen ihnen in NEO4J über den Batch -Endpunkt von REST -API, ca. 5K -Datensätze/s (immer noch zunehmend), einfügen.

Dies wird eine kontinuierliche Einführung rund um die Uhr sein. Jeder Datensatz erfordert möglicherweise nur einen Knoten, aber andere erfordern möglicherweise zwei Knoten und eine Beziehung, die erstellt wird.

Kann ich die Leistung der Einsätze verbessern, indem ich mein Verfahren ändern oder die Einstellungen von NEO4J ändern?

Mein bisheriger Fortschritt:

1. Ich habe schon eine Weile bei Neo4J getestet, aber ich konnte nicht die Leistung bekommen, die ich brauchte

Testserverbox: 24 Kerne + 32 GB RAM

NEO4J 2.0.0-m06 als eigenständiger Service installiert.

Ausführen meiner Java -Anwendung auf demselben Server (Neo4J und Java App müssen in Zukunft auf ihrem eigenen Server ausgeführt werden, sodass der eingebettete Modus nicht verwendet werden kann)

Rest API Endpunkt: /db /data /batch (Ziel: /Cypher)

Verwenden von Schema -Index, Einschränkungen, verschmelzen, eindeutig erstellen.

2. Mein Schema:

neo4j-sh (0)$ schema
==> Indexes
==>   ON :REPLY(created_at)   ONLINE                             
==>   ON :REPLY(ids)          ONLINE (for uniqueness constraint) 
==>   ON :REPOST(created_at) ONLINE                             
==>   ON :REPOST(ids)        ONLINE (for uniqueness constraint) 
==>   ON :Post(userId)      ONLINE                             
==>   ON :Post(postId)    ONLINE (for uniqueness constraint) 
==> 
==> Constraints
==>   ON (post:Post) ASSERT post.postId IS UNIQUE
==>   ON (repost:REPOST) ASSERT repost.ids IS UNIQUE
==>   ON (reply:REPLY) ASSERT reply.ids IS UNIQUE

3. Meine Cypher -Abfragen und JSON -Anfragen

3.1. Wenn ein Datensatz eine einzelne Knotenerstellung erfordert, sieht die Stellenbeschreibung nach unten aus

{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (child:Post {postId:1001, userId:901})"}}

3.2. Wenn ein Datensatz erforderlich ist, um zwei Knoten mit einer Beziehung zu erstellen, sieht die Stellenbeschreibung nach unten aus

{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (parent:Post {postId:1002, userId:902}) MERGE (child:Post {postId:1003, userId:903}) CREATE UNIQUE parent-[relationship:REPOST {ids:'1002_1003', created_at:'Wed Nov 06 14:06:56 AST 2013' }]->child"}}

3.3. Normalerweise sende ich 100 Stellenbeschreibungen (gemischt 3,1 und 3,2) pro Charge, wodurch ungefähr 150 ~ 250 ms dauert, um dies zu erledigen.

4. Leistungsprobleme

4.1. Parallelität:

/db/data/batch (target:/cypher) scheint nicht zu fadensicher zu sein, getestet mit zwei oder mehr gleichzeitigen Threads, die den NEO4J -Server innerhalb der Sekunden (s) ~ Minute (en) herunterbrachten.

4.2. Zusammenführen mit Einschränkungen funktioniert nicht immer.

Beim Erstellen von zwei Knoten und einer Beziehung mit einer einzelnen Abfrage (oben in 3.2 erwähnt) funktioniert es irgendwann wie ein Zauber. Aber es schlägt manchmal mit einer Cypherexexexexception aus und sagt, dass einer der Knoten XXXX bereits mit dem Label AAAA und der Eigenschaft "BBBBB" = [CCCCC] existiert; Nach meinem Verständnis wird die Zusammenführung nicht angenommen, eine Ausnahme zurückzugeben, sondern den Knoten zurückzugeben, wenn er bereits existiert.

Als Ergebnis der Ausnahme schlägt die gesamte Charge aus und rollt zurück, was sich auf meine Einfügungsrate auswirkt.

Ich habe ein Problem in GitHub für dieses Problem eröffnet. https://github.com/neo4j/neo4j/issues/1428

4.3. Erstellen Sie einzigartig mit Einschränkungen nicht immer für die Erstellung von Beziehungen.

Dies wird auch in demselben Github -Problem erwähnt.

4.4. Leistung:

Bevor ich Batch mit Cypher verwende, habe ich die Legacy -Indexierung mit get_or_create (/db/daten/node/node/post? Uniqueness = get_or_create &/db/data/index/relation/xxxxx? Uniqueness = get_or_create) ausprobiert.

Aufgrund der Art dieser Legacy -Index -Endpunkte (sie geben den Ort der Daten im Index stattdessen an den Daten der Daten in der tatsächlichen Datenspeicherung zurück), sodass ich sie nicht innerhalb der Stapel verwenden konnte (erforderte die Funktion des früheren Überweisungsknotens, das früher im selben Charge erstellt wurde ))

Ich weiß, dass ich auto_indexing aktivieren und direkt mit dem Datenspeicher anstelle des Legacy -Index umgehen kann. Aus 2.0.0 wird jedoch ein Schema -Index für den Legacy Index empfohlen.

Mit Batch + Cypher kann ich jedoch nur etwa 200 Stellenbeschreibungen pro Sekunde einfügen, es wäre viel höher gewesen, wenn die Zusammenführung mit Einschränkungen immer funktioniert hat, sagen wir etwa 600 ~ 800/s, aber es ist immer noch viel niedriger als 5K /s. Ich habe auch den Schema -Index ohne Einschränkung ausprobiert, er hat eine noch niedrigere Leistung in Bezug auf die Einfügungsrate erzielt.

War es hilfreich?

Lösung

Mit 2.0 würde ich den Transaktionsendpunkt verwenden, um Ihre Aussagen in Stapeln, z. B. 100 oder 1000 pro HTTP-Anforderung und etwa 30K-50k pro Transaktion (bis Sie festzulegen) erstellen.

Siehe dies für das Format des neuen Transaktionsendpunkts des Streaming:

http://docs.neo4j.org/chunked/milestone/rest-api-transactional.html

Auch für eine solche hohe Leistung empfehle ich, eine Servererweiterung zu schreiben, die gegen die eingebettete API ausgeführt wird, und kann problemlos 10k oder mehr Knoten und Beziehungen pro Sekunde einfügen. Hier finden Sie die Dokumentation:

http://docs.neo4j.org/chunked/milestone/server-unmanaged-extessions.html

Für reine Einsätze brauchen Sie keine Cypher. Und für die Parallelität nehmen Sie einfach ein Sperre mit einem bekannten Knoten (pro Subgraph, den Sie einfügen) Schloss, damit gleichzeitige Einsätze kein Problem sind, dies mit dem mit tx.acquireWriteLock() oder durch Entfernen einer nicht existierenden Eigenschaft aus einem Knoten (REMOVE n.__lock__).

Schauen Sie sich dieses Projekt an, um eine nicht verwaltete Erweiterung zu schreiben (aber CYPHER). Es verfügt sogar über einen Modus, der Ihnen helfen könnte (CSV -Dateien auf den Serverendpunkt zu veröffentlichen, um mit einer CYPHER -Anweisung pro Zeile ausgeführt zu werden).

https://github.com/jexp/cypher-rs

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top