Neo4j数据库大小增长

时间:2016-06-11 07:23:49

标签: neo4j graph-databases

我正在使用neo4j 3.0.1社区,我有几GB的数据。这些数据很快就会过时(比如每天2,3次),我必须首先创建新数据,然后删除旧的东西(所以在任何时候某些数据都可用)。

问题是neo4j不会从已删除的节点/关系中重用空间。 我使用MATCH(n)WHERE条件DETEACH DELETE n

我可以看到节点被删除了(它们的数量是恒定的~30M)但是尺寸正在增长(经过12次更新后,尺寸几乎比它应该大12倍)。

我发现以前的帖子 Neo4J database size / shrinkingstore-utils,但我想找到更好的解决方案。

我还发现了一个旧问题(来自版本1.x)neostore.* file size after deleting millions node,但它至少在我的案例中并没有像答案一样工作。

有一些建议要删除所有数据库文件并只创建一个新文件,但它需要停止服务,这不应该发生。

我还发现了一些信息,为了重用空间,你需要先重新启动数据库,然后尝试它并且它不起作用。

有没有办法从已删除的节点/关系中有效地释放/重用空间?也许我想念一些配置,或仅在企业版中可用?

编辑:

最后,我有一些时间进行测试,并且在数据刷新几次时运行方案,重启服务器几次。在Windows 10环境下对neo4j 3.0.0进行了测试。结果是(尚未允许嵌入图像):

neo4j storage sizes

每列显示进一步更新的存储大小,蓝线表示neo4j服务器重新启动,最后一列(用棕色线分隔)代表运行store-utils后的大小。

如前所述,尺寸增长速度非常快,对文档而言,重启并没有帮助。只有store-utils有帮助(他们清理除neostore.nodestore.db之外的文件),但将store-utils集成到生产解决方案中将是一个困难而混乱的解决方案。

任何人都可以给我一个暗示存储增长的原因吗?

3 个答案:

答案 0 :(得分:1)

从Neo4j 3.0.4开始,Enterprise Edition确实支持重用节点ID和关系ID,而无需重新启动实例。这适用于单实例和HA部署。

要启用该功能,您需要在neo4j.conf中设置以下内容:

 dbms.ids.reuse.types.override=NODE,RELATIONSHIP

答案 1 :(得分:0)

您可以在创建新数据后重新启动服务器,因此下次创建数据时它将重复使用您上次释放的块,这样您只能获得2倍的卷(如果您必须先保留数据)在删除之前)。

你应该仍然使用store-utils来第一次压缩你的商店。

答案 2 :(得分:0)

经过大量测试后,我终于找到了问题的主要来源 - 事实证明我在neo4j服务器上做了一个他无法处理的硬关机,结果他在删除节点/关系并重复使用空格后苦苦挣扎。

让我们从头开始。 我在docker下使用neo4j(使用docker compose)。 我的场景非常简单,每隔几个小时我就会开始一个我添加几GB节点的过程,在完成之后我将从之前的过程中删除节点(非常简短)。有时我必须更新neo4j插件或做一些需要我重启服务器的工作,这就是问题开始的地方。我正在用docker-compose重新启动它,它永远不会等待neo4j优雅地退出(默认情况下,当我知道问题时我必须自定义它),而是立即杀死他。在debug.log中没有停止服务器的痕迹。 Neo4j没有处理它,结果他做了很奇怪的事情。当我启动服务器时,他回滚了nodeId计数器,relationshipId计数器和其他人,并且在节点/关系之后没有释放空间,但至少他从不回滚节点和关系本身。当然,我的删除操作在事务中成功提交,因此不是恢复未提交的更改的情况。在几次重启和导入后,我有一个数据库大小乘以导入数。节点计数器也被夸大了。

我意识到我杀死neo4j主要是我的错,但在我看来这种行为仍不理想。

还有另一个相关问题。我进行了差不多24小时的测试而没有重新开始,在此期间我重复我的场景超过20次。关于每次导入的时间增长(跳过不断增长的数据库大小问题)我感到非常惊讶

import nr。 |创建节点时间|删除节点时间

1 | 20分钟| 0分钟(还没有删除)

2 | 20分钟| 8分钟

3 | 20分钟| 12分钟

...

~20 | 20分钟|超过80分钟

正如您所看到的,节点/关系很可能不会立即删除(可能在停止/启动时实际上已删除),我的删除脚本必须执行大量额外工作。

这是我删除的代码:

String REMOVE_OLD_REVISION_NODES_QUERY =
    "MATCH (node) " +
                "WHERE node.revision <> {" + REVISION_PARAM + "} " +
                "WITH node LIMIT 100000 " +
                "DETACH DELETE node " +
                "RETURN count(node) as count";
LOG.info("Removing nodes with revision different than: {}", revision);
long count;
do {
    count = (long) graphDb.execute(REMOVE_OLD_REVISION_NODES_QUERY, ImmutableMap.of(REVISION_PARAM, revision)).columnAs("count").next();
} while (count > 0);

我可能能够解决杀死neo4j的问题(添加一些脚本,确保neo4j能够优雅地停止)当我重新启动docker镜像时,但不确定是否有办法处理不断增长的大小和删除时间(除非我每次更新后重新启动neo4j)。

我正在描述这个问题,所以也许有一天会帮助某人,或者帮助neo4j团队改进他们的产品,因为这是我曾经使用过的最令人愉快的数据库,尽管我必须处理这些问题。