在我的项目中,我使用了spring-data-neo4j 4.2.0.M1和neo4j-ogm 2.0.4。最初,这是使用嵌入式neo4j实例,但在调查这个问题的过程中,我已经使用Bolt协议迁移到专用的neo4j实例(尽管在同一台计算机上运行)。Neo4j-ogm:减少写入/映射性能
我不断地插入数据,基本上,因为它变得可用于我的应用程序(所以我不能使用批量插入)。启动后,这工作正常,并保存我的NodeEntity实例需要〜60ms,这对我的使用情况来说非常好。然而,随着时间的推移,这会逐渐降低10-20分钟后,每次保存速度减慢到约2秒,这已经不再那么好了。时间似乎在这里达到顶峰,并没有减少太多。
最初我认为这是由嵌入式实例太小造成的,因为我看到了有关由neo4j报告的GC暂停的重复消息。然后,我已经迁移到一个更大的专用实例,并且这些GC警告不再显示。虽然降解仍然发生。
存储大小如Neo4j的报道:
Array Store 8.00 KiB
Logical Log 151.36 MiB
Node Store 40.14 MiB
Property Store 1.83 GiB
Relationship Store 742.63 MiB
String Store> Size 120.87 MiB
Total Store Size 4.55 GiB
的实例提供配置如下:(!取样模式)
dbms.memory.pagecache.size=5g
dbms.memory.heap.initial_size=4g
dbms.memory.heap.max_size=4g
dbms.jvm.additional=-XX:+UseG1GC
使用YourKit探查我可以看到,大部分的时间似乎由Neo4j的,OGM的EntityGraphMapper在
org.neo4j.ogm.context.EntityGraphMapper#haveRelationEndsChanged
度过的,特别是210
正在保存的NodeEntity通常与其他节点具有约40个关系,其中大多数关系建模为RelationshipEntity。在较早的阶段,我已经注意到保存实体的速度很慢,因为也有太多相关的实体(但没有变化)。从那时起,我在保存时使用的深度为1。 导致NodeEntitites被保存的连续操作使用200个实体的事务大小。
我还不确定,neo4j-ogm实际上是放缓的原因,因为我没有看到与良好的初始结果相比有什么变化。 在这种情况下,我通常会怀疑内存泄漏/污染,但是在我的应用程序中,所有监视结果都非常好。对于neo4j服务器实例,除了debug.log之外,我不知道在哪里查找这些信息。
总而言之,我已经花了相当一段时间调查这一点,不知道还有什么要看。任何想法或建议?我很高兴提供更多信息。
编辑:Follwing @文斯的投入,我已经再看看内存分配和发现,其实Neo4jSession已经让应用程序运行于〜3小时后成长颇多:
那时堆是1,7 GB大,其中70%参考了实时数据。除此之外,Neo4jSession目前引用了大约300MB(并保持活跃)。这可能表明它已经变得太大了。 我该如何手动干预?
您是否为每个交易(一批200个实体)或使用单个会话创建新会话? – Vince
我正在使用同一个会话(我认为)。我没有任何手动处理会话,也使用默认范围。从我从文档中了解的情况来看,对于长时间运行的操作,这应该是有益的性能表现?在此期间,我不希望在我的工作线程以外有任何更新。 – geld0r
实体在会话中继续存在,直到他们收集垃圾。如果您加载了数千个实体,那么在'haveRelationEndsChanged'中可能会有一些性能影响,所以在每个事务之间执行'session.clear()'可能会有帮助。 – Vince