查询时Neo4J OutOfMemory错误

查询时Neo4J OutOfMemory错误,neo4j,Neo4j,我最近开始使用Neo4J,到目前为止,我还没有找到解决问题的方法,特别是在服务器方面。我使用的是1.8.1版,在Windows上作为服务运行服务器,而不是嵌入式。我的图表有大约700万个节点和近1100万个关系 通过小查询和成倍的查询,事情运行得很好。然而,当我试图撤回更复杂的查询(可能是数千行)时,事情就会变得糟糕。如果我正在使用控制台,我将什么也得不到,几分钟或更长时间后,单词undefined出现了(它试图用Javascript做些什么,但我不确定是什么)。如果我在.NET中使用Neo4J

我最近开始使用Neo4J,到目前为止,我还没有找到解决问题的方法,特别是在服务器方面。我使用的是1.8.1版,在Windows上作为服务运行服务器,而不是嵌入式。我的图表有大约700万个节点和近1100万个关系

通过小查询和成倍的查询,事情运行得很好。然而,当我试图撤回更复杂的查询(可能是数千行)时,事情就会变得糟糕。如果我正在使用控制台,我将什么也得不到,几分钟或更长时间后,单词undefined出现了(它试图用Javascript做些什么,但我不确定是什么)。如果我在.NET中使用Neo4JClient,它将超时(我正在通过WCF服务进行此操作),我怀疑我的问题是服务器端的

下面是一个在控制台中导致我出现问题的密码查询示例:

start begin = node:idx(ID="1234")
MATCH begin-[r1?:RELATED_TO]-n1-[r2?:RELATED_TO]-n2-[r3?:RELATED_TO]-n3-[r4?:RELATED_TO]-n4
RETURN begin.Title?, r1.RelationType?, n1.Title?, r2.RelationType?, n2.Title?, r3.RelationType?, n3.Title?, r4.RelationType?, n4.Title?;
我查看了日志,发现以下严重错误:

SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuffer.append(Unknown Source)
    at java.io.StringWriter.write(Unknown Source)
    at java.io.PrintWriter.newLine(Unknown Source)
    at java.io.PrintWriter.println(Unknown Source)
    at java.io.PrintWriter.println(Unknown Source)
    at org.neo4j.cypher.PipeExecutionResult$$anonfun$dumpToString$1.apply(PipeExecutionResult.scala:96)
    at org.neo4j.cypher.PipeExecutionResult$$anonfun$dumpToString$1.apply(PipeExecutionResult.scala:96)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.immutable.List.foreach(List.scala:45)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:96)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:124)
    at org.neo4j.cypher.javacompat.ExecutionResult.toString(ExecutionResult.java:90)
    at org.neo4j.shell.kernel.apps.Start.exec(Start.java:72)
    at org.neo4j.shell.kernel.apps.ReadOnlyGraphDatabaseApp.execute(ReadOnlyGraphDatabaseApp.java:32)
    at org.neo4j.shell.impl.AbstractAppServer.interpretLine(AbstractAppServer.java:127)
    at org.neo4j.shell.kernel.GraphDatabaseShellServer.interpretLine(GraphDatabaseShellServer.java:92)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:130)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:114)
    at org.neo4j.server.webadmin.rest.ShellSession.evaluate(ShellSession.java:96)
    at org.neo4j.server.webadmin.rest.ConsoleService.exec(ConsoleService.java:123)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
从一个有根据的猜测的角度来看堆栈跟踪,是不是我收回了太多的记录?因为它在扩展StringBuffer时内存不足

我一直想知道GC是否能发挥作用,所以我找到了GCViewer。这似乎不是垃圾收集,如果您认为它有用的话,我可以从GCViewer添加一个屏幕截图

我已经将JVM分配到默认值和8G内存之间的任意位置。以下是我的配置文件中的一些设置(我将尝试只包括相关的设置)。如果你还需要什么,请告诉我

Neo4J.特性

# Default values for the low-level graph engine
use_memory_mapped_buffers=false

# Keep logical logs, helps debugging but uses more disk space, enabled for legacy reasons
keep_logical_logs=true
# HTTP logging is disabled. HTTP logging can be enabled by setting this property to 'true'.
org.neo4j.server.http.log.enabled=false 
Neo4J-server.properties

# Default values for the low-level graph engine
use_memory_mapped_buffers=false

# Keep logical logs, helps debugging but uses more disk space, enabled for legacy reasons
keep_logical_logs=true
# HTTP logging is disabled. HTTP logging can be enabled by setting this property to 'true'.
org.neo4j.server.http.log.enabled=false 
Neo4J-Wrapper.conf(可能是不恰当地缝在一起)


任何帮助都将不胜感激。

您的问题太复杂了。当您拥有如此大的图形以确保不会达到堆内存限制时,必须分配适当的内存。您可能想使用以下配置玩一玩:

但是,您的查询可以简化为:

start begin = node:idx(ID="1234")
MATCH p=begin-[r1:RELATED_TO*0..4]-n4
RETURN p

Craig问题是,你使用的Neo4j外壳只是一个ops工具,只是在发回之前收集内存中的数据,它从来没有打算处理巨大的结果集


您可能希望在启用流式处理的情况下直接对http端点运行查询(
X-Stream:true
http头),这样您就不会再有问题了。

是否尝试使用结果流式处理?它可以减少所需的缓冲量@Louis,没有,但是通过阅读文档中的部分,如果可能的话,它可能会解决这个问题。是否可以在webadmin中使用流媒体?我猜它还不在Neo4JClient中,因为它提到它是新的。我不能提供完整的答案,我只是在最近的文档中才看到它。另一种选择是使用分页来避免构建如此大的结果集。我很少把增加可用内存看作是一个长期的解决方案。我同意,虽然我尝试过将内存增加到8G(现在是这样),但没有成功,所以这甚至不是一个短期的解决方案。谢谢你的指点。如果没有更好的答案,我将尝试分页,直到找到一种使用流媒体的方法。我使用Windows,我相信Neo在Windows上处理内存映射的方式不同,将堆空间的一半分配给内存映射。换言之,更改这些设置会有任何影响吗?至于您的查询改进,它看起来肯定更好了,谢谢,从现在起我将尝试使用路径来处理这个特定的查询。我认为neo4j内存处理与平台无关,因为所有内存都是由java自己处理的。取决于您的java运行时环境,但据我所知,OSI之间的堆映射应该没有区别,最终删除了neo4j.properties中的行,在该行中,我显式关闭了内存映射,并将映射重新配置为:neostore.nodestore.db.mapped_memory=250M neostore.relationshipstore.db.mapped_memory=500Mneostore.propertystore.db.mapped_memory=500M neostore.propertystore.db.strings.mapped_memory=750M neostore.propertystore.db.arrays.mapped_memory=0M我将暂时将此标记为答案,因为情况似乎更好!我无论如何都无法使异常再次出现。这是否意味着Neo4J无法处理大型结果集?使用
LIMIT
SKIP
会有所帮助。只需多次运行同一查询,但在第一次运行时附加
limit 100 skip 0
,在第二次运行时附加
limit 100 skip 100
,以此类推,直到没有得到所有结果为止。您可以尝试找到运行查询次数尽可能少的最高限制数。我不同意这违反了图形数据库的精神。我基本上要做的是从一个起始节点找到所有附近和中间范围的节点。像SELECT*这样的SQL不是我在这里要做的。我知道,至少SQL Server在找到结果后会将结果流式传输回客户端。因此,随着流媒体支持和文档的改进,这个问题可能会自行解决。