2016-06-11 4 views
3

Ich benutze neo4j 3.0.1 Community, und ich habe ein paar GBs Daten. Diese Daten werden sehr schnell veraltet (wie 2,3 Mal pro Tag) und ich muss zuerst neue Daten erstellen und dann die alten Daten löschen (so sind zu jedem Zeitpunkt einige Daten verfügbar).Neo4j Datenbankgröße wächst

Das Problem ist, dass neo4j nicht Speicherplatz aus gelöschten Knoten/Beziehungen wiederverwenden. Im mit MATCH (n) WHERE Bedingung DETEACH LÖSCHEN n

Ich kann sehen, dass Knoten gelöscht werden (ihre Zahl ist konstant ~ 30M), aber die Größe wächst (nach 12 Updates, Größe ist fast genau 12x größer als es sollte sein).

Ich fand bisherigen Beiträge Neo4J database size/shrinking über store-utils aber ich möchte eine bessere Lösung zu finden.

Ich fand auch alte Frage (von Version 1.x) neostore.* file size after deleting millions node, aber es funktioniert einfach nicht wie in der Antwort zumindest in meinem Fall.

Es gibt einige Ratschläge, alle Datenbankdateien zu löschen und nur eine neue zu erstellen, aber es müsste der Dienst gestoppt werden, was nicht passieren sollte.

Ich fand auch einige Informationen, dass, um Platz wiederzuverwenden Sie müssen DB zuerst neu starten, versuchte es auch und es hat nicht funktioniert.

Gibt es eine Möglichkeit, Speicherplatz von gelöschten Knoten/Beziehungen effektiv freizugeben/wiederzuverwenden? Vielleicht fehlt mir eine Konfiguration, oder sie ist nur in der Enterprise-Version verfügbar?

EDIT:

Schließlich hatte ich einige Zeit zu testen und ich laufe Szenario, wenn die Daten ein paar Mal aufgefrischt wurden, Server als gut ein paar Mal neu zu starten. Der Test wurde mit neo4j 3.0.0 unter Windows 10 durchgeführt. Die Ergebnisse sind (noch nicht zu embeed Bildern erlaubt):

neo4j storage sizes

Jede Spalte Speichergröße für weiteres Updates präsentiert, blaue Linie bedeutet Neo4j Neustart des Server, und die letzte Spalte (mit brauner Linie getrennt) steht für Größe nach Laufende Store-Utils.

Wie bereits erwähnt, wächst die Größe ziemlich schnell und gegen die Dokumentation, Neustart hilft nicht. Nur store-utils hilft (sie säubern Dateien außer neostore.nodestore.db), aber es wäre eine harte und chaotische Lösung, store-utils in die Produktionslösung zu integrieren.

Kann mir jemand einen Hinweis geben, warum der Speicher wächst?

Antwort

0

Sie können Ihren Server neu starten, nachdem Sie Ihre neuen Daten erstellt haben. Wenn Sie also das nächste Mal Daten erstellen, werden die zuvor freigegebenen Blöcke wieder verwendet, sodass Sie nur das doppelte Volumen haben (wenn Sie die Daten behalten müssen) zuerst bevor Sie es löschen).

Sie sollten store-utils verwenden, um Ihr Geschäft zum ersten Mal zu komprimieren.

+0

Ich habe gerade das getan, aber der Platz wurde nicht wiederverwendet. Ich bin mir nicht sicher, ob das einen Unterschied macht, aber ich lasse neo4j in einem Andock-Container laufen und starte den ganzen Container neu (also schätze ich, dass neo4j nicht gut aufhört). Ich bin auch ziemlich positiv, dass wenn ich neo4j ohne Docker getestet habe, es nicht auch Platz wiederverwendet hat. Ich starte neo4j mit dem Befehl 'neo4j console' und stoppe den Prozess. – Rychu

+0

bearbeiteter Originalbeitrag, der ein Testergebnis hinzufügt – Rychu

1

Beginnend mit Neo4j 3.0.4 unterstützt Enterprise Edition die Wiederverwendung für Knoten-IDs und Beziehungs-IDs, ohne dass die Instanz neu gestartet werden muss. Dies funktioniert sowohl für Einzelinstanzen als auch HA-Bereitstellungen.

zu ermöglichen, die Funktion, die Sie die folgend in neo4j.conf festlegen müssen:

dbms.ids.reuse.types.override=NODE,RELATIONSHIP 
+0

Beachten Sie jedoch, dass mit 3.0.4 Enterprise nur RELATIONSHIP-Typen zur Wiederverwendung unterstützt werden. https://github.com/neo4j/neo4j/pull/7555 – InverseFalcon

0

Nach schwerer Prüfung schließlich ich wichtigste Quelle des Problems gefunden - es stellt sich heraus, dass ich eine harte Abschaltung auf Neo4j Server tat der er kann nicht damit umgehen und im Ergebnis kämpfte er damit, Knoten/Beziehungen zu löschen und den Raum nach ihnen wiederzuverwenden.

Lets am Anfang beginnen. Ich benutzte neo4j unter docker (mit Docker komponieren). Mein Szenario war sehr einfach, alle paar Stunden beginne ich einen Prozess, bei dem ich ein paar GB Knoten hinzufüge, und nachdem ich fertig bin, entferne ich Knoten aus dem vorherigen Prozess (sehr kurz). Manchmal muss ich das neo4j-Plugin aktualisieren oder einige Aufgaben ausführen, bei denen ich den Server neu starten muss und das Problem beginnt. Ich starte es neu mit docker-compose und es wartet nie darauf, dass neo4j elegant beendet wird (standardmäßig muss ich es jetzt anpassen, wenn ich über das Problem weiß), stattdessen tötet er ihn sofort. In debug.log gibt es keine Spur von dem Beenden des Servers. Neo4j geht damit nicht klar und im Ergebnis macht er sehr seltsame Sache. Wenn ich den Server starte, führt er einen Rollback des NodeId-Counters, des countificationId-Counters und anderer aus und räumt den Space nach Knoten/Beziehungen nicht frei, aber er rollt zumindest nie Nodes und Beziehungen selbst zurück. Natürlich wurden meine Löschvorgänge in einer Transaktion erfolgreich ausgeführt, es handelt sich also nicht darum, nicht festgeschriebene Änderungen rückgängig zu machen. Nach ein paar Neustarts und Importe habe ich eine Datenbankgröße multipliziert mit der Anzahl der Importe. Auch Knotenzähler sind stark überzeichnet.

Ich weiß, dass es meistens meine Schuld, dass ich Neo4j tötete, aber immer noch das Verhalten ist meiner Meinung nach nicht ideal.

Es gibt auch ein anderes Problem in Zusammenhang. Ich habe einen fast 24-Stunden-Test ohne Neustarts durchgeführt, währenddessen ich mein Szenario über 20 Mal wiederholt habe. Ich war über das Erwachsenzeit jeden Import sehr überrascht (wachsende Datenbank Größe Ausgabe Skipping)

Import nr. | Erstellen von Knoten Zeit | Zeit löschen

1 | 20 Minuten | 0 min (nichts löschen noch)

2 | 20 Minuten | 8 Minuten

3 | 20 Minuten | 12 Minuten

...

~ 20 | 20 Minuten | über 80 Minuten

Wie Sie sehen können, werden Knoten/Beziehungen höchstwahrscheinlich nicht sofort gelöscht (vielleicht werden sie tatsächlich beim Start/Stopp gelöscht) und mein Lösch-Skript muss viel zusätzliche Arbeit erledigen.

, dass mein Code zum Entfernen ist:

String REMOVE_OLD_REVISION_NODES_QUERY = 
    "MATCH (node) " + 
       "WHERE node.revision <> {" + REVISION_PARAM + "} " + 
       "WITH node LIMIT 100000 " + 
       "DETACH DELETE node " + 
       "RETURN count(node) as count"; 
LOG.info("Removing nodes with revision different than: {}", revision); 
long count; 
do { 
    count = (long) graphDb.execute(REMOVE_OLD_REVISION_NODES_QUERY, ImmutableMap.of(REVISION_PARAM, revision)).columnAs("count").next(); 
} while (count > 0); 

Ich bin wahrscheinlich in der Lage Problem zu lösen mit Neo4j Tötung (ein Skript hinzufügen, die das Neo4j der Lage ist, ordnungsgemäß zu stoppen gewährleisten), wenn i Docker Bild bin Neustart , aber nicht sicher, ob es eine Möglichkeit gibt, wachsende Größe und Zeit des Löschens zu bewältigen (es sei denn, ich starte neo4j nach jedem Update neu).

Ich beschreibe das Problem, vielleicht hilft es jemandem irgendwann, oder helfe neo4j-Team, ihr Produkt zu verbessern, weil es am angenehmsten DB ist, mit dem ich je gearbeitet habe, trotz der Probleme, mit denen ich zu tun habe.