我使用BatchInserter从neo4j数据库获取特定属性和关系,以使用BatchInserterIndex编写新索引(带有数字索引)。
大约10分钟后,索引文件夹的大小为4.7G,内存已充分使用,垃圾收集速度非常慢,经过一段时间后,VM以垃圾收集器异常结束。
代码看起来大致如下:
final BatchInserter bInserter = BatchInserters.inserter(this.dbStoreDir, getConfig());
final BatchInserterIndexProvider bIndexInserterProvider = new LuceneBatchInserterIndexProvider(bInserter);
final BatchInserterIndex bIndexInserter = bIndexInserterProvider.nodeIndex(indexName, getConfig());
try {
final Map<String, Object> propMap = new HashMap<>();
for (final Long id : idSet) {
this.filterProperties(bInserter.getNodeProperties(id), propMap);
for (final BatchRelationship rel : bInserter.getRelationships(id)) {
if (rel.getType().name().equals(ANYREL)) {
final Long subNodeId = rel.getEndNode();
this.filterProperties(bInserter.getNodeProperties(subNodeId).entrySet(), propMap);
this.filterProperties(bInserter.getRelationshipProperties(rel.getId()).entrySet(), propMap);
}
}
bIndexInserter.add(id, propMap);
propMap.clear();
}
} finally {
bIndexInserter.flush();
bInserter.shutdown();
bIndexInserterProvider.shutdown();
}
public static Map<String, String> getConfig() {
final Map<String, String> config = new HashMap<>();
config.put("dump_configuration", "false");
config.put("cache_type", "none");
config.put("use_memory_mapped_buffers", "true");
config.put("node_cache_size", "2G");
config.put("relationship_cache_size", "800M");
config.put("neostore.propertystore.db.index.keys.mapped_memory", "200M");
config.put("neostore.propertystore.db.index.mapped_memory", "200M");
config.put("neostore.nodestore.db.mapped_memory", "200M");
config.put("neostore.relationshipstore.db.mapped_memory", "500M");
config.put("neostore.propertystore.db.mapped_memory", "250M");
config.put("neostore.propertystore.db.strings.mapped_memory", "250M");
config.put("type", "exact");
return config;
}
我使用以下Java VM选项:
-D64 -Xmx13G -Xmn1G -server -XX:+UseNUMA -XX:+UseParallelGC
在具有16GB RAM和Java 1.7_60
的计算机上a)我做错了什么?
b)什么记忆?是lucene还是neo4j?
c)迈克尔·亨格尔在batch importer中采取了哪些不同的做法?我在代码中看了一眼,但我真的不知道他是怎么做的。