0

我正在将数据批量导入以服务器模式运行的 neo4j 实例(我已经针对 2.2.0 社区和企业版以及 2.1.7 社区运行)。我的应用程序在内存中创建了一堆节点,并且会定期停止编写一系列 .csv 文件并将 cypher 发送到 neo4j 实例以上传文件。(这样做是因为使用普通的旧 REST API 运行应用程序时的性能问题)。

总的来说,我希望上传 150-50 亿个节点,所以原则上,这是 neo4j 声称能够相对较好地处理的类型。

好吧,无论如何,当我对生产数据运行此程序时,我注意到的是应用程序以两种状态运行——一种是 csv 上传每秒处理 2k-8k 个节点,另一种是处理 80-200 个节点每秒节点数。当您将上传视为时间序列时,这两种状态是交织在一起的,随着时间的推移,它会在缓慢状态下花费越来越长的时间。

节点是通过一系列

MERGE (:{NODE_TYPE} {csvLine.key = n.primaryKey}) on create set [PROPERTY LIST];

声明,并且我对我正在合并的所有内容都有索引。这感觉不像是插入语句中的降级,因为减速不是线性的,而是双峰的,这感觉就像在 neo4j 实例中存在垃圾收集一样。为频繁批量插入调整 neo4j JVM 垃圾收集器的最佳方法是什么?

neo4j.properties:

neostore.nodestore.db.mapped_memory=50M
neostore.relationshipstore.db.mapped_memory=500M
#neostore.relationshipgroupstore.db.mapped_memory=10M
neostore.propertystore.db.mapped_memory=100M
#neostore.propertystore.db.strings.mapped_memory=130M
neostore.propertystore.db.arrays.mapped_memory=130M

neo4j-wrapper.conf:

wrapper.java.additional=-XX:+UseConcMarkSweepGC
wrapper.java.additional=-XX:+CMSClassUnloadingEnabled
wrapper.java.additional=-XX:-OmitStackTraceInFastThrow
wrapper.java.additional=-XX:hashCode=5

wrapper.java.initmemory=8194
wrapper.java.maxmemory=8194

这感觉就像是整体堆内存和 Neostore 东西的最佳选择。增加整体堆会降低性能。也就是说,neo4j 垃圾收集日志经常有 GC(分配失败)消息。

编辑:回应迈克尔饥饿:

这台机器有 64 GB 的 RAM,似乎什么都没有用完。似乎任何时候都只使用少量内核。垃圾收集器分析显示垃圾收集器似乎运行得相当频繁。

确切的密码语句是,例如:

USING PERIODIC COMMIT 110000 LOAD CSV WITH HEADERS FROM 'file:///home/jschirmer/Event_2015_4_773476.csv' AS csvLine MERGE (s:Event {primaryKey: csvLine.primaryKey}) ON CREATE SET s.checkSum= csvLine.checkSum,s.epochTime= toInt(csvLine.epochTime),s.epochTimeCreated= toInt(csvLine.epochTimeCreated),s.epochTimeUpdated= toInt(csvLine.epochTimeUpdated),s.eventDescription= csvLine.eventDescription,s.fileName= csvLine.fileName,s.ip= csvLine.ip,s.lineNumber= toInt(csvLine.lineNumber),s.port= csvLine.port,s.processPid= csvLine.processPid,s.rawEventLine= csvLine.rawEventLine,s.serverId= csvLine.serverId,s.status= toInt(csvLine.status);

USING PERIODIC COMMIT 110000 LOAD CSV WITH HEADERS FROM 'file:///home/jschirmer/Event__File_2015_4_773476.csv' AS csvLine MATCH (n:SC_CSR{primaryKey: csvLine.Event_id}), (s:File{fileName: csvLine.File_id}) MERGE n-[:DATA_SOURCE]->s;

虽然有几个这样的语句,我已经尝试了一个并发事务以及并行运行几个(~3)这样的语句(这大约提高了 2 倍)。我已经尝试调整定期提交频率和文件大小。当 csv 文件大约有 100k 行时,这似乎可以最大限度地提高性能,这意味着确实可以关闭定期提交。

我没有在语句上运行配置文件。我会这样做,但我认为通过在 create 语句上使用 MERGE ... 可以避免急切的合并问题。

4

1 回答 1

0

一般来说,您的配置看起来不错,您的机器有什么 RAM?

对于您合并的内容,我建议使用约束而不是索引。

你的 tx 大小是多少?你运行多少并发 tx?

你可以分享具体的语句,而不是你的通用合并语句(不会编译)吗?

你对这些陈述进行了描述吗?也许你遇到了急切的管道问题:

http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/

你使用定期提交吗?

您的 CSV 文件有多大?

见: http: //neo4j.com/developer/guide-import-csv/

于 2015-04-07T21:38:38.540 回答