gpt4 book ai didi

在 neo4j 中使用大量数据的 Java 堆空间错误

转载 作者:行者123 更新时间:2023-11-29 03:30:25 27 4
gpt4 key购买 nike

我目前正在根据将大量节点/关系插入到图中来评估 neo4j。这与可以通过批量插入实现的初始插入无关。它是关于在嵌入式模式下使用 neo4j 的 java 应用程序在运行时频繁处理的插入(当前版本 1.8.1,因为它随 spring-data-neo4j 2.2.2.RELEASE 一起提供)。

这些插入通常是遵循星形模式 的节点。一个节点(导入数据集的根节点)有多达 1000000(一百万!) 个连接的子节点。子节点通常也与其他附加节点有关系。但到目前为止,这些关系并未包含在该测试中。 总体目标是在最多五分钟内导入该数量的数据!

为了模拟此类插入,我编写了一个小型 junit 测试,它使用 Neo4jTemplate 创建节点和关系。每个插入的叶子都有一个关联的键以供以后处理:

@Test
@Transactional
@Rollback
public void generateUngroupedNode()
{
long numberOfLeafs = 1000000;
Assert.assertTrue(this.template.transactionIsRunning());
Node root = this.template.createNode(map(NAME, UNGROUPED));
String groupingKey = null;
for (long index = 0; index < numberOfLeafs; index++)
{
// Just a sample division of leafs to possible groups
// Creates keys to be grouped by to groups containing 2 leafs each
if (index % 2 == 0)
{
groupingKey = UUID.randomUUID().toString();
}
Node leaf = this.template.createNode(map(GROUPING_KEY, groupingKey, NAME, LEAF));
this.template.createRelationshipBetween(root, leaf, Relationships.LEAF.name(),
map());
}
}

对于此测试,我使用 gcr 缓存来避免垃圾收集器问题:

cache_type=gcr
node_cache_array_fraction=7
relationship_cache_array_fraction=5
node_cache_size=400M
relationship_cache_size=200M

此外,我将 MAVEN_OPTS 设置为:

export MAVEN_OPTS="-Xmx4096m -Xms2046m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit"

但无论如何,在运行该测试时,我总是得到一个 Java heap space 错误:

java.lang.OutOfMemoryError: Java heap space
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
at java.lang.Class.getMethod0(Class.java:2670)
at java.lang.Class.getMethod(Class.java:1603)
at org.apache.commons.logging.LogFactory.directGetContextClassLoader(LogFactory.java:896)
at org.apache.commons.logging.LogFactory$1.run(LogFactory.java:862)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.commons.logging.LogFactory.getContextClassLoaderInternal(LogFactory.java:859)
at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:423)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
at org.springframework.transaction.support.TransactionTemplate.<init>(TransactionTemplate.java:67)
at org.springframework.data.neo4j.support.Neo4jTemplate.exec(Neo4jTemplate.java:403)
at org.springframework.data.neo4j.support.Neo4jTemplate.createRelationshipBetween(Neo4jTemplate.java:367)

我用较少的数据做了一些测试,结果如下。 1 个节点连接到:

  • 50000 片叶子:3035 毫秒
  • 100000 片叶子:4290 毫秒
  • 200000 片叶子:10268 毫秒
  • 400000 片叶子:20913ms
  • 800000 叶:Java 堆空间

这是这些操作期间系统监视器的屏幕截图:

System Monitor

为了更好地了解什么正在运行并存储在堆中,我在最后一次测试(800000 个叶子)中运行了 JProfiler。以下是一些屏幕截图:

堆使用情况:

HEAP

CPU 使用率:

CPU

对我来说最大的问题是:neo4j 不是为使用这种海量数据而设计的吗?还是有其他方法可以实现这种插入(以及以后的操作)?在 neo4j 官方网站和各种截屏视频中,我发现 neo4j 能够运行数十亿个节点和关系的信息(例如 http://docs.neo4j.org/chunked/stable/capabilities-capacity.html )。我没有找到任何可用的功能,例如 flush()clean() 方法,例如在 JPA 中手动保持堆清洁。

如果能够将 neo4j 用于这些数据量,那就太好了。图中已经存储了 200000 个叶子,我注意到与嵌入式经典 RDBMS 相比,性能提高了 10 倍甚至更多。我不想放弃像 neo4j 提供的数据建模和查询这些数据的好方法。

最佳答案

仅使用 Neo4j 核心 API,创建子项需要 18 到 26 秒,我的 MacBook Air 没有任何优化:

输出:导入 1000000 个 child 用了 26 秒。

public class CreateManyRelationships {

public static final int COUNT = 1000 * 1000;
public static final DynamicRelationshipType CHILD = DynamicRelationshipType.withName("CHILD");
public static final File DIRECTORY = new File("target/test.db");

public static void main(String[] args) throws IOException {
FileUtils.deleteRecursively(DIRECTORY);
GraphDatabaseService gdb = new GraphDatabaseFactory().newEmbeddedDatabase(DIRECTORY.getAbsolutePath());
long time=System.currentTimeMillis();
Transaction tx = gdb.beginTx();
Node root = gdb.createNode();
for (int i=1;i<= COUNT;i++) {
Node child = gdb.createNode();
root.createRelationshipTo(child, CHILD);
if (i % 50000 == 0) {
tx.success();tx.finish();
tx = gdb.beginTx();
}
}
tx.success();tx.finish();
time = System.currentTimeMillis()-time;
System.out.println("import of "+COUNT+" children took " + time/1000 + " seconds.");
gdb.shutdown();
}
}

和 Spring Data Neo4j docs state , 它不是为这种类型的任务而制作的

关于在 neo4j 中使用大量数据的 Java 堆空间错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18575783/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com