Neo4j潜在内存泄漏

ilmyapht  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(151)

我们正在使用apoc插件从neo4j db中删除节点,但观察到内存使用率很高。我们看到临时内存删除,但在我们的例子中没有发生。我们正在使用社区版,所以我们无法诊断太多。
我已经为此打开了issue

"CALL
apoc.periodic.iterate("MATCH (cl:Node1 {id: '" + label1 + "'}) -[:BELONGS]-> (c) return c","DETACH DELETE c",
{ batchSize: " + deleteBatchSize + ", parallel: " + deleteParallelCheck + ", concurrency: " + deleteConcurrencySize + ", retries: " + deleteRetriesAttempts + " })"

字符串
以下是相同的参数:

delete.parallel.check=true
delete.batch.size=2000
delete.concurrency.size=20
delete.retries.attempts=3

z0qdvdin

z0qdvdin1#

给定您的用例,只要一个批处理开始工作,它的事务就会阻塞所有其他批处理,直到它完成为止。因此,并行执行查询是没有意义的,因为它会消耗大量资源,而不会获得任何东西。

说明

每当一个事务删除一个关系时,一个写锁被放置在该关系及其结束节点上(因为它们都必须以某种方式被修改)。阻止其他事务更新相同的实体。
在您的用例中,DETACH DELETE c删除c节点及其BELONGS关系。但是 * 所有 * 要删除的BELONGS关系都连接到 * 相同的 * cl节点(假设Node1节点具有唯一的id值)。
因此,只要一个批处理(事务)开始删除关系,它就会在单个共享cl上施加一个写锁,所有其他批处理都必须等待(并占用内存),直到第一批处理完成并释放cl上的写锁。然后场景重复。
并非所有用例都适合并行化。

总结

不要并行执行查询。只需直接执行以下操作(其中$id1作为parameter传递):

MATCH (:Node1 {id: $id1})-[:BELONGS]->(c)
DETACH DELETE c

字符串
[更新]
如果有许多c节点要删除,那么使用上面的查询可能会耗尽内存,因为所有操作都是在一个事务中完成的。
为了避免这种情况,您可以使用apoc.periodic.iterate批量执行删除(根据您的情况使用适当的批量大小):

CALL apoc.periodic.iterate(
  "MATCH (:Node1 {id: $id1})-[:BELONGS]->(c)",
  "DETACH DELETE c",
  {batchSize: 5000})


请注意,我们将过程的parallel配置参数默认为false,以避免写锁阻塞问题。

相关问题