我的Neo4j非常简单。只有一种类型的节点和一种可以绑定节点的关系。每个节点都有一个属性(索引),每个关系有四个属性。这些是数字:
neo4j-sh (?)$ dbinfo -g "Primitive count"
{
"NumberOfNodeIdsInUse": 19713210,
"NumberOfPropertyIdsInUse": 109295019,
"NumberOfRelationshipIdsInUse": 44903404,
"NumberOfRelationshipTypeIdsInUse": 1
}
我在Debian,7核和26GB RAM的虚拟机上运行这个数据库。这是我的Neo4j配置:
neo4j.properties:
neostore.nodestore.db.mapped_memory=3000M
neostore.relationshipstore.db.mapped_memory=4000M
neostore.propertystore.db.mapped_memory=4000M
neostore.propertystore.db.strings.mapped_memory=300M
neostore.propertystore.db.arrays.mapped_memory=300M
的Neo4j-wrapper.conf:
wrapper.java.additional=-XX:+UseParallelGC
#wrapper.java.additional=-XX:+UseConcMarkSweepGC
wrapper.java.additional=-XX:+CMSClassUnloadingEnabled
wrapper.java.initmemory=2000
wrapper.java.maxmemory=10000
我使用UseParallelGC而不是UseConcMarkSweepGC,因为我注意到使用UseConcMarkSweepGC在查询期间只使用了一个CPU核心,当我改为UseParallelGC时,所有核心都被使用。我没有并行运行任何查询。在neo4j-shell中一次只有一个,但主要涉及整个节点集,例如:
match (n:User)-->(k:User)
return n.id, count(k) as degree
order by degree desc limit 100;
执行它需要726230毫秒。我也尝试过:
match (n:User)-->()-->(k:User)
return n.id, count(DISTINCT k) as degree
order by degree desc limit 100;
但很长一段时间后我只得到“服务器线程出错;嵌套异常是: java.lang.OutOfMemoryError:超出GC开销限制“。我没有尝试考虑关系属性的限制查询,但它也是计划好的。 我认为我的配置不是最佳的。我注意到Neo4j在查询期间最多使用50%的系统内存,剩余内存是免费的。我可以通过在wrapper.java.maxmemory中设置更大的值来改变它,但我已经读过我必须为mapped_memory setings留下一些内存。但是,我不确定它们是否被考虑在内,因为在查询期间有很多可用内存。我该如何设置此类查询的配置?
答案 0 :(得分:1)
您的查询是全局查询,随着数据量的增加而变慢。对于每个用户节点,计算传出关系的数量,将其放入集合中并按计数排序。这种操作会消耗大量的CPU和内存。而不是调整配置,我猜你最好不要重构你的图模型。
根据您的使用情况,考虑将用户的degree
存储在用户节点的属性中。当然,为用户添加/删除关系的任何操作都需要反映在degree
属性中。此外,您可能希望索引degree
属性。