Neo4j批处理插入器非常慢,会创建巨大的数据库文件
我正试图从CSV文件中向Neo4j 2.0.3插入一个相对较小的图形(2M关系,几个100K节点)。此文件中的每一行都是一个关系。我正在使用BatchInserterAPI 为了测试代码,我使用了输入文件的一个子集。当这个子集很大时,插入运行得很快(几秒钟包括JVM启动)。当它有1000个关系时,导入需要20分钟,生成的数据库大小为130 GB!更奇怪的是,5000次恋爱的结果(在时间和空间上)完全相同。在20分钟内,99%的时间用于将GBs写入磁盘 我不明白这里发生了什么。我尝试过用以下各种设置配置插入器Neo4j批处理插入器非常慢,会创建巨大的数据库文件,neo4j,Neo4j,我正试图从CSV文件中向Neo4j 2.0.3插入一个相对较小的图形(2M关系,几个100K节点)。此文件中的每一行都是一个关系。我正在使用BatchInserterAPI 为了测试代码,我使用了输入文件的一个子集。当这个子集很大时,插入运行得很快(几秒钟包括JVM启动)。当它有1000个关系时,导入需要20分钟,生成的数据库大小为130 GB!更奇怪的是,5000次恋爱的结果(在时间和空间上)完全相同。在20分钟内,99%的时间用于将GBs写入磁盘 我不明白这里发生了什么。我尝试过用以下各种设
文件
.asCharSource(新文件(“/path/to/input.csv”)、Charsets.UTF_8)
.readLines(新的LineProcessor(){
BatchInserter inserter=BatchInserters.inserter(
“/path/to/db”,
新HashMap(){{
put(“转储配置”、“错误”);
put(“缓存类型”、“无”);
put(“使用内存映射缓冲区”、“真”);
put(“neostore.nodestore.db.mapped_memory”,“500M”);
put(“neostore.relationshipstore.db.mapped_memory”,“1G”);
put(“neostore.propertystore.db.mapped_memory”,“500M”);
put(“neostore.propertystore.db.strings.mapped_memory”,“500M”);
}}
);
RelationshipType RelationshipType=
DynamicRelationshipType.withName(“relationshipType”);
Set createdNodes=new HashSet();
@重写公共布尔处理行(字符串行)引发IOException{
String[]components=line.split(“\\\\”);
long sourceId=parseLong(组件[1]);
long targetId=parseLong(组件[3]);
如果(!createdNodes.contains(sourceId)){
createdNodes.add(sourceId);
createNode(sourceId,newhashmap());
}
如果(!createdNodes.contains(targetId)){
createdNodes.add(targetId);
createNode(targetId,newHashMap());
}
inserter.createRelationship(
sourceNodeId、targetNodeId、relationshipType、新HashMap();
返回true;
}
@重写公共Void getResult(){
inserter.shutdown();
返回null;
}
});
我把代码弄乱了,偶然发现了解决方案
事实证明,如果我调用createNode
,而不指定节点ID,那么它工作得非常好
我之所以指定节点ID,是因为API允许这样做,所以让节点ID与输入文件中的ID匹配很方便
猜测根本原因:节点可能存储在一个按其ID索引的连续数组中。我输入文件中的大多数ID都很小(4位),但有些可以是12位。因此,当我尝试插入其中一个节点时,Neo4j会将一个千兆字节长的数组写入磁盘,以便将该节点放在末尾。也许有人能证实这一点。令人惊讶的是,这种行为似乎没有记录在确认的。中。节点ID是文件中固定大小记录的索引。你不应该自己编造…谢谢你的确认。
createNode
的文档应该反映这一点。就是这样。一旦我删除了id覆盖,它就开始工作了。自述文件不应显示此方法
Files
.asCharSource(new File("/path/to/input.csv"), Charsets.UTF_8)
.readLines(new LineProcessor<Void>() {
BatchInserter inserter = BatchInserters.inserter(
"/path/to/db",
new HashMap<String, String>() {{
put("dump_configuration","false");
put("cache_type","none");
put("use_memory_mapped_buffers","true");
put("neostore.nodestore.db.mapped_memory","500M");
put("neostore.relationshipstore.db.mapped_memory","1G");
put("neostore.propertystore.db.mapped_memory","500M");
put("neostore.propertystore.db.strings.mapped_memory","500M");
}}
);
RelationshipType relationshipType =
DynamicRelationshipType.withName("relationshipType");
Set<Long> createdNodes = new HashSet<>();
@Override public boolean processLine(String line) throws IOException {
String[] components = line.split("\\|");
long sourceId = parseLong(components[1]);
long targetId = parseLong(components[3]);
if (!createdNodes.contains(sourceId)) {
createdNodes.add(sourceId);
inserter.createNode(sourceId, new HashMap<>());
}
if (!createdNodes.contains(targetId)) {
createdNodes.add(targetId);
inserter.createNode(targetId, new HashMap<>());
}
inserter.createRelationship(
sourceNodeId, targetNodeId, relationshipType, new HashMap<>());
return true;
}
@Override public Void getResult() {
inserter.shutdown();
return null;
}
});