Cypher 查询删除属性导致 neo4j 内存不足错误-shell
Cypher query removing properties results in out-of-memory error in neo4j-shell
我有一个超过 1500 万个节点的大型网络。我想在 neo4-shell.
中使用 Cypher 查询从所有这些中删除 属性 "CONTROL"
如果我尝试执行以下任一操作:
- MATCH (n) WHERE has(n.`CONTROL`) REMOVE n.`CONTROL` RETURN COUNT(n);
- MATCH (n) WHERE has(n.`CONTROL`) REMOVE n.`CONTROL`;
- 匹配 (n) 删除 n.`CONTROL`;
系统returns:
Error occurred in server thread; nested exception is:
java.lang.OutOfMemoryError: Java heap space
即使是以下查询也会出现 OutOfMemoryError:
- 匹配 (n) 删除 n.`CONTROL` RETURN n.`ID` LIMIT 10;
作为测试,以下命令确实可以正确执行:
- MATCH (n) WHERE has(n.`CONTROL`) RETURN COUNT(n);
返回 16636351。
一些细节:
内存限制取决于以下设置:
- wrapper.java.maxmemory (conf/neo4j-wrapper.conf)
- neostore..._memory (conf/neo4j.properties)
通过在两个文件中将这些值设置为总计 28 GB,导致 java_pidXXX.hprof 文件大约 45 GB(wrapper.java.additional=-XX:+HeapDumpOnOutOfMemoryError)。
我能google的唯一线索是:
...you use the Neo4j-Shell which is just an ops tool and just collects the data in memory before sending back, it was never meant to handle huge result sets.
使用 neo4j-shell 和 cypher 真的无法删除大型网络中的属性吗?或者我做错了什么?
PS
附加信息:
Neo4j 版本:2.1.3
Java 版本:Java(TM) SE Runtime Environment (build 1.7.0_76-b13) 和 OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75 -2.5.4-1~trusty1)
数据库为 7.4 GB(16636351 个节点,14724489 个关系)
属性"CONTROL"是空的,也就是说,它只是为所有节点定义的,而没有实际分配属性值。
来自 data/console.log 的异常示例:
java.lang.OutOfMemoryError:Java堆space
正在将堆转储到 java_pid20541.hprof ...
转储文件不完整:文件大小限制
线程异常 "GC-Monitor" 线程异常 "pool-2-thread-2" java.lang.OutOfMemoryError: Java 堆 space
在 java.util.Arrays.copyOf(Arrays.java:2271)
在 java.lang.StringCoding.safeTrim(StringCoding.java:79)
在 java.lang.StringCoding.access300 美元(StringCoding.java:50)
在 java.lang.StringCoding$StringEncoder.encode(StringCoding.java:305)
在 java.lang.StringCoding.encode(StringCoding.java:344)
在 java.lang.StringCoding.encode(StringCoding.java:387)
在 java.lang.String.getBytes(String.java:956)
在 ch.qos.logback.core.encoder.LayoutWrappingEncoder.convertToBytes(LayoutWrappingEncoder.java:122)
在 ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:135)
在 ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:194)
在 ch.qos.logback.core.FileAppender.writeOut(FileAppender.java:209)
在 ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:219)
在 ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:103)
在 ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88)
在 ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
在 ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:273)
在 ch.qos.logback.classic.Logger.callAppenders(Logger.java:260)
在 ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:442)
在 ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:396)
在 ch.qos.logback.classic.Logger.warn(Logger.java:709)
在 org.neo4j.kernel.logging.LogbackService$Slf4jToStringLoggerAdapter.warn(LogbackService.java:243)
在 org.neo4j.kernel.impl.cache.MeasureDoNothing.run(MeasureDoNothing.java:84)
java.lang.OutOfMemoryError: Java 堆 space
在 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.addConditionWaiter(AbstractQueuedSynchronizer.java:1857)
在 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1079)
在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
在 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
在 java.lang.Thread.run(Thread.java:745)
线程 "Statistics Gatherer[primitives]" java.lang.OutOfMemoryError 中的异常:Java 堆 space
线程 "RMI RenewClean-[10.65.4.212:42299]" java.lang.OutOfMemoryError 中的异常:Java 堆 space
线程异常 "RMI RenewClean-[10.65.4.212:43614]" java.lang.OutOfMemoryError: Java 堆 space
看这里:http://jexp.de/blog/2013/05/on-importing-data-in-neo4j-blog-series/
要使用 Cypher 更新数据,还需要考虑交易大小。对于嵌入式案例,批处理事务将在本系列的下一部分中讨论。对于通过 Neo4j REST API 的远程执行,有几件重要的事情需要记住。特别是对于大型索引查找和匹配结果,查询可能会更新数十万个元素。那么可以在updating操作前加上一个使用WITH和SKIP/LIMIT的分页机制
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WITH a, count(*) AS cnt
SKIP {offset} LIMIT {pagesize}
SET a.movie_count = cnt
RETURN count(*)
运行 pagesize=20000 增加 offset=0,20000,40000,... 直到查询 returns a count < pagesize
所以在你的情况下,重复这个直到它 returns 0 行。您也可以将限制增加到 1M。
MATCH (n) WHERE has(n.`CONTROL`)
WITH n
LIMIT 100000
REMOVE n.`CONTROL`
RETURN COUNT(n);
我有一个超过 1500 万个节点的大型网络。我想在 neo4-shell.
中使用 Cypher 查询从所有这些中删除 属性 "CONTROL"如果我尝试执行以下任一操作:
- MATCH (n) WHERE has(n.`CONTROL`) REMOVE n.`CONTROL` RETURN COUNT(n);
- MATCH (n) WHERE has(n.`CONTROL`) REMOVE n.`CONTROL`;
- 匹配 (n) 删除 n.`CONTROL`;
系统returns:
Error occurred in server thread; nested exception is: java.lang.OutOfMemoryError: Java heap space
即使是以下查询也会出现 OutOfMemoryError:
- 匹配 (n) 删除 n.`CONTROL` RETURN n.`ID` LIMIT 10;
作为测试,以下命令确实可以正确执行:
- MATCH (n) WHERE has(n.`CONTROL`) RETURN COUNT(n);
返回 16636351。
一些细节:
内存限制取决于以下设置:
- wrapper.java.maxmemory (conf/neo4j-wrapper.conf)
- neostore..._memory (conf/neo4j.properties)
通过在两个文件中将这些值设置为总计 28 GB,导致 java_pidXXX.hprof 文件大约 45 GB(wrapper.java.additional=-XX:+HeapDumpOnOutOfMemoryError)。
我能google的唯一线索是:
...you use the Neo4j-Shell which is just an ops tool and just collects the data in memory before sending back, it was never meant to handle huge result sets.
使用 neo4j-shell 和 cypher 真的无法删除大型网络中的属性吗?或者我做错了什么?
PS
附加信息:
Neo4j 版本:2.1.3
Java 版本:Java(TM) SE Runtime Environment (build 1.7.0_76-b13) 和 OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75 -2.5.4-1~trusty1)
数据库为 7.4 GB(16636351 个节点,14724489 个关系)
属性"CONTROL"是空的,也就是说,它只是为所有节点定义的,而没有实际分配属性值。
来自 data/console.log 的异常示例:
java.lang.OutOfMemoryError:Java堆space 正在将堆转储到 java_pid20541.hprof ... 转储文件不完整:文件大小限制 线程异常 "GC-Monitor" 线程异常 "pool-2-thread-2" java.lang.OutOfMemoryError: Java 堆 space 在 java.util.Arrays.copyOf(Arrays.java:2271) 在 java.lang.StringCoding.safeTrim(StringCoding.java:79) 在 java.lang.StringCoding.access300 美元(StringCoding.java:50) 在 java.lang.StringCoding$StringEncoder.encode(StringCoding.java:305) 在 java.lang.StringCoding.encode(StringCoding.java:344) 在 java.lang.StringCoding.encode(StringCoding.java:387) 在 java.lang.String.getBytes(String.java:956) 在 ch.qos.logback.core.encoder.LayoutWrappingEncoder.convertToBytes(LayoutWrappingEncoder.java:122) 在 ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:135) 在 ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:194) 在 ch.qos.logback.core.FileAppender.writeOut(FileAppender.java:209) 在 ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:219) 在 ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:103) 在 ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88) 在 ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48) 在 ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:273) 在 ch.qos.logback.classic.Logger.callAppenders(Logger.java:260) 在 ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:442) 在 ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:396) 在 ch.qos.logback.classic.Logger.warn(Logger.java:709) 在 org.neo4j.kernel.logging.LogbackService$Slf4jToStringLoggerAdapter.warn(LogbackService.java:243) 在 org.neo4j.kernel.impl.cache.MeasureDoNothing.run(MeasureDoNothing.java:84) java.lang.OutOfMemoryError: Java 堆 space 在 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.addConditionWaiter(AbstractQueuedSynchronizer.java:1857) 在 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1079) 在 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807) 在 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang.Thread.run(Thread.java:745) 线程 "Statistics Gatherer[primitives]" java.lang.OutOfMemoryError 中的异常:Java 堆 space 线程 "RMI RenewClean-[10.65.4.212:42299]" java.lang.OutOfMemoryError 中的异常:Java 堆 space 线程异常 "RMI RenewClean-[10.65.4.212:43614]" java.lang.OutOfMemoryError: Java 堆 space
看这里:http://jexp.de/blog/2013/05/on-importing-data-in-neo4j-blog-series/
要使用 Cypher 更新数据,还需要考虑交易大小。对于嵌入式案例,批处理事务将在本系列的下一部分中讨论。对于通过 Neo4j REST API 的远程执行,有几件重要的事情需要记住。特别是对于大型索引查找和匹配结果,查询可能会更新数十万个元素。那么可以在updating操作前加上一个使用WITH和SKIP/LIMIT的分页机制
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WITH a, count(*) AS cnt
SKIP {offset} LIMIT {pagesize}
SET a.movie_count = cnt
RETURN count(*)
运行 pagesize=20000 增加 offset=0,20000,40000,... 直到查询 returns a count < pagesize
所以在你的情况下,重复这个直到它 returns 0 行。您也可以将限制增加到 1M。
MATCH (n) WHERE has(n.`CONTROL`)
WITH n
LIMIT 100000
REMOVE n.`CONTROL`
RETURN COUNT(n);