【问题标题】:OutOfMemoryError when importing GraphML into OrientDB将 GraphML 导入 OrientDB 时出现 OutOfMemoryError
【发布时间】:2023-08-18 08:43:01
【问题描述】:

我在 OrientDB 中导入一个中等大小的 GraphML 文件(大约 8GB),但我不断收到以下错误:

Importing GRAPHML database from database /root/neo/out.graphml...
Error: java.lang.OutOfMemoryError: GC overhead limit exceeded

我尝试在本地或作为远程数据库 (remote:localhost) 连接到我的数据库,但无济于事。公平地说,远程连接有帮助,但还不够。我还尝试调整控制台应用程序和数据库服务器本身的堆大小(最高为 2048)。这也有帮助,但还不够,我不清楚到底是哪一个帮助了。

我想知道导入过程的哪一部分需要这么多堆内存,因为 OrientDB 本身不使用堆内存进行数据库操作。哪个代理(加载 graphml 的控制台或保存导入结果的数据库)在这里需要更多的堆内存,在这种情况下,将内存分配给 java 堆的最佳方式是什么?最后:与远程连接到同一台机器上的同一个本地数据库(远程:localhost)相比,当我在本地连接到数据库时,内存分配需求是否存在差异?

【问题讨论】:

  • 您是针对 plocal 还是远程导入?尝试更快更轻的 plocal。
  • 正如我上面所说,我都尝试过。实际上,我注意到使用远程(更好的并行支持?)时性能有所提高。尽管如此,我还是会出现内存不足的错误。

标签: java memory import heap-memory orientdb


【解决方案1】:

经过一天的反复试验,我成功了。这是我尝试和工作的:

OrientDB 的控制台会将整个 GraphML 文件加载到 Java 堆内存中,然后再将其导入数据库。它需要的最大堆大小至少与您的 GraphML 文件一样大。解决方案是在$orientdb/bin/console.sh 中设置控制台的最大堆大小。在我的情况下,这意味着将 JAVA_OPTS="-Xmx8192m" 添加到脚本的第 43 行。

OrientDB 的控制台不适合并行处理。尽管数据库操作大多受 IO 限制,但在导入图形数据时,这成为限制因素。解决方案是在使用控制台时远程而不是本地连接到 OrientDB。具体来说,您可能需要运行以下命令,而不是建议的create database plocal:/tmp/db/testcreate database remote:localhost/test USERNAME PASSWORD plocal

导入全部 7 GB 数据(超过 400 万个顶点和超过 3700 万条边)花费了 48 多个小时。顶点的导入速度非常快,而边缘的导入速度约为每秒 1000 条记录(8 核,SSD)。

Here是全过程的记录。

【讨论】:

    【解决方案2】:

    正如 orientdb documentation 建议的那样,您可以使用 batchSize 参数来减少要处理的批处理大小。默认情况下它是 1000。所以你可以尝试类似

    控制台

    orientdb {db=test}> IMPORT DATABASE /tmp/out.graphml batchSize=100
    

    JAVA API

    new OGraphMLReader(new OrientGraph("plocal:/temp/bettergraph")).setBatchSize(100).inputGraph("/temp/neo4j.graphml");
    

    【讨论】:

    • 当时这在 GraphML 上不起作用,我认为它现在也不起作用。不过,如果您的数据源是线性文件(CSV 等),它确实有效。