2017-01-09 2 views
1

Ich betreibe TomEE (Art von Tomcat) Server auf Java 8 und mit Titan 1.0.0 mit Cassandra Backend und Elasticsearch Index als meine Datenbank. In meiner Entwicklungsumgebung mit kleiner Benutzerverbindung funktioniert alles perfekt, aber auf meinem Produktionsserver mit vielen Benutzern, die mit vielen DB-Zugriffen verbunden sind, haben wir ein Problem mit Speicherlecks, wahrscheinlich weil Titan Graph Cache oder etwas Titan relativ ist. Ich habe 4GB Heap-Größe konfigurieren und nach mehr als 10 Stunden Laufzeit Speicher auf Heap zu seinem Maximum (~ 300Mb pro Stunde) wächst und es bewirkt, dass GC (Garbage Collector) kann nicht mehr aufräumen und bleibt kontinuierlich zu laufen bewirkt, dass die Serverinstanz nicht mehr reagiert. Mit VisualVM Ich habe einige Speicherprofilierung und das sind meine screenshots: Allocated memory graph
Heap histogram Alle Vorschläge, wie wir dieses Problem beheben oder den Weg finden, diese Frage in mehr Details zu untersuchen? Könnten einige GC Params uns in diesem Fall helfen?Titan 1.0.0 Graph Cache-Speicher Lecks

Antwort

2

Ich habe diese Probleme zuvor auf Titan 1.0 mit Cassandra gesehen. Zwei Dinge zu überprüfen:

Öffnen und Schließen der Graph

Sind Sie verschiedene Transaktion auf den Graphen pro Benutzer oder verschiedene Diagramme pro Benutzer öffnen? dh sind Sie tun:

(1)

//User 1 Logs in 
graph = TitanFactory.open(config); 
soStuffWithGraph(graph); 
//User 2 Logs in 
graph = TitanFactory.open(config); 
soStuffWithGraph(graph); 

oder

(2)

graph = TitanFactory.open(config); 
//User 1 Logs in 
soStuffWithGraph(graph); 
//User 2 Logs in 
soStuffWithGraph(graph); 

Approach (1) bedeutet, dass jeder Benutzer auf das Diagramm ihre eigene Verbindung wird mit ihr eigenes Grafikobjekt. Dies ist sehr schwer und führt zu mehr Speicherverbrauch.

Ansatz (2) bedeutet, dass jeder Benutzer die gleiche Verbindung, aber verschiedene Transaktionen verwendet. Dies ist meiner Meinung nach vorzuziehen. Hinweis: Dies setzt voraus, dass sich Benutzer in verschiedenen Threads befinden.

Lange lebte Transaktionen

Das ist das Problem, das ich hatte, die sich in ähnlichen GC Problemen. Ich habe Transaktionen einfach zu lange am Leben gehalten. Um die Abfrage von Titan zu beschleunigen, wird viel zwischengespeichert und ich denke nicht, dass es den Cache löscht, wenn die Transaktion nicht geschlossen wird. Idealerweise sollten Sie Folgendes haben:

graph = TitanFactory.open(config); 
//User 1 Logs in 
soStuffWithGraph(graph); 
graph.tx().close(); 
//User 2 Logs in 
soStuffWithGraph(graph); 
graph.tx().close(); 

wo jede Transaktion geschlossen wird, nachdem ein Benutzer damit fertig ist.

+0

Ich verwende den zweiten Ansatz. Ich habe eine geöffnete Verbindung zum Graphen und öffne die neue Transaktion 'TitanTransaction tt = graph.newTransaction()' für jede Benutzeranfrage. Jede Transaktion ist kurz (Hinzufügen oder Aktualisieren von ein oder zwei Scheitelpunkten oder Kanten ODER Abfrage von Daten aus Scheitelpunkten) und am Ende der Transaktion wird immer 'tt.commit()' oder roll-backed 'tt.rollback()' im Falle eines Fehlers festgeschrieben (bevor eine Ausnahme ausgelöst wird) – OctopusSD

+0

Verwenden Sie 'graph.newTransaction()', dann erstellen Sie [multithreaded Transaktionen] (http://s3.thinkaurelius.com/docs/titan/1.0.0/tx.html#) Multi-thread-tx), die ein ganz neues Transaktionshandhabungsobjekt erzeugt, das auch ziemlich schwer und immer offen ist.Wenn Sie * explizit * einen für jeden Benutzer erstellen, sollten Sie definitiv 'tt.close()' am Ende aufrufen. Ansonsten bleibt es offen. –

+1

Von Titan [Dokumentation] (http://s3.thinkaurelius.com/docs/titan/1.0.0/index.html) und [javadoc] (http://titan.thinkaurelius.com/javadoc/1.0.0/)) Ich dachte, dass 'tt.commit() 'und' tt.rollback() 'die Transaktion schließen, ABER nach dem Hinzufügen von' tt.close() 'neben jedem Commit und Rollback löst es unsere Speicherlecks. – OctopusSD