Neo4j 潜在的内存泄漏

问题描述 投票:0回答:1

我们正在使用 apoc 插件从 Neo4j 数据库中删除节点,但观察到内存使用率很高。我们看到临时内存被删除,但在我们的例子中没有发生。我们使用的是社区版,所以我们无法诊断太多。

我为此打开了一个问题

"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
memory neo4j out-of-memory spring-data-neo4j neo4j-apoc
1个回答
0
投票

根据您的用例,一旦批次开始工作,其事务就会阻塞所有其他批次,直到完成。因此,并行执行查询是没有意义的,因为它会消耗大量资源,但不会为您带来任何好处。

说明

每当事务删除关系时,就会在关系及其结束节点上放置写锁(因为它们都必须以某种方式进行修改)。这会阻止其他事务更新相同的实体。

在您的用例中,

DETACH DELETE c
删除
c
节点及其
BELONGS
关系。但是要删除的所有
BELONGS
关系都连接到同一个
cl
节点(假设
Node1
节点具有唯一的
id
值)。

因此,一旦批处理(事务)开始删除关系,它就会对单个共享

cl
施加写入锁定,并且所有其他批处理都必须等待(并占用内存),直到第一个批处理完成并释放写入锁定
cl
。然后场景就会重复。

并非所有用例都适合并行化。

结论

不要并行执行查询。只需直接执行类似这样的操作(其中

$id1
作为 参数 传递):

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
,以避免写锁定阻塞问题。

© www.soinside.com 2019 - 2024. All rights reserved.