2017-01-09 1 views
1

Je courais tomee (type de Tomcat) cache sur Java 8 et en utilisant Titan avec back-end 1.0.0 Cassandra et l'indice ElasticSearch comme ma base de données. Dans mon environnement de développement avec une petite connexion utilisateur tout fonctionne parfaitement mais sur mon serveur de production avec beaucoup d'utilisateurs connectés avec beaucoup d'accès db nous avons un problème avec des fuites de mémoire probablement parce que le cache Titan ou quelque chose de relatif. J'ai configuré la taille de tas de 4GB et après plus de 10 heures de mémoire allouée d'exécution sur le tas grandit à son maximum (~ 300Mb par heure) et cela fait que GC (garbage collector) ne peut plus nettoyer et reste pour continuer provoque l'instance de serveur à ne pas répondre. En utilisant VisualVM je l'ai fait un certain profilage de la mémoire et ce sont mes captures d'écran: Allocated memory graph
Heap histogram Tout suggérer comment nous pouvons résoudre ce problème ou de trouver le moyen d'enquêter sur cette question dans plus de détails? Peut-être que certains paramètres GC peuvent nous aider dans ce cas?serveur Titan graphique 1.0.0 fuites de mémoire

Répondre

2

J'ai déjà vu ces problèmes sur Titan 1.0 avec Cassandra. Deux choses à vérifier:

Ouverture et fermeture du graphique

Vous ouvrez différentes transactions au graphique par des graphiques utilisateur ou différents par utilisateur? à-dire êtes-vous faire:

(1)

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

ou

(2)

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

approche (1) signifie que chaque utilisateur obtient leur propre connexion au graphique avec leur propre objet graphique. Ceci est très lourd et conduit à plus d'utilisation de la mémoire. L'approche (2) signifie que chaque utilisateur utilise la même connexion mais des transactions différentes. C'est préférable à mon avis. Remarque: Cela suppose que les utilisateurs se trouvent sur des threads différents.

longue durée de vie Transactions

C'est le problème que j'avais ce qui a entraîné des problèmes de GC semblables à vous-même. J'ai simplement gardé les transactions en vie pendant trop longtemps. Pour accélérer l'interrogation des caches Titan et je ne pense pas qu'elle efface le cache sauf si la transaction est fermée. Donc, idéalement, vous devriez avoir quelque chose comme:

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

où chaque transaction est fermée après qu'un utilisateur en ait fini avec lui.

+0

J'utilise la deuxième approche. J'ai une connexion ouverte au graphique et ouvre une nouvelle transaction 'TitanTransaction tt = graph.newTransaction()' pour chaque demande d'utilisateur. Chaque transaction est courte (ajouter ou mettre à jour un ou deux sommets ou arêtes OU interroger des données de sommets) et à la fin de la transaction est toujours commise 'tt.commit()' ou roll-backed 'tt.rollback()' en cas d'échec (avant de lancer une exception) – OctopusSD

+0

Utilisez-vous 'graph.newTransaction()' alors vous créez [transactions multi-threads] (http://s3.thinkaurelius.com/docs/titan/1.0.0/tx.html# multi-thread-tx) qui crée un nouvel objet de gestion de transaction qui est aussi lourd et toujours ouvert.Si vous en créez * explicitement un pour chaque utilisateur, vous devriez certainement appeler 'tt.close()' à la fin. Sinon, il restera ouvert. –

+1

De Titan [documentation] (http://s3.thinkaurelius.com/docs/titan/1.0.0/index.html) et [javadoc] (http://titan.thinkaurelius.com/javadoc/1.0.0/) Je pensais que 'tt.commit()' et 'tt.rollback()' fermerait la transaction BUT après avoir ajouté 'tt.close()' à côté de chaque validation et restauration, il résout nos fuites de mémoire. – OctopusSD