我尝试使用neo4j做一些关于SNS的实验。我创建了一个由100万用户,10万个项目组成的随机图表,每个用户有大约100个朋友和100个最喜欢的项目。因此图中有大约100万个节点和2亿个关系,图形文件占用4.8GB。所有节点只有一个id,我为它们创建了索引。 现在我已经使用Java API来设置一个小型集群来维护这个由三个虚拟机组成的图形。每个虚拟机都有 16GB RAM,Intel Xeon CPU 2.00GHz(8核)。以下是一些配置:
config.put( "neostore.nodestore.db.mapped_memory", "150M");
config.put("neostore.relationshipstore.db.mapped_memory", "5G");
config.put( "neostore.propertystore.db.mapped_memory", "100M");
config.put( "neostore.propertystore.db.strings.mapped_memory", "130M");
config.put( "neostore.propertystore.db.arrays.mapped_memory", "130M");
config.put( "node_auto_indexing", "true");
config.put( "use_memory_mapped_buffers", "true");
config.put( "neostore.propertystore.db.index.keys.mapped_memory", "150M");
config.put( "neostore.propertystore.db.index.mapped_memory", "150M");
我使用gcr cache_type。我只是通过遍历来预热图表:
for ( Node n : GlobalGraphOperations.at(db).getAllNodes() ) {
n.getPropertyKeys();
for ( Relationship relationship : n.getRelationships() ) {
start = relationship.getStartNode();
}
}
密码查询:
start user=node:users({key}={value}) match user-[:FRIEND]->(friend)-[:LIKES]->(item) return item, collect(friend), count(0) order by count(0) desc limit 32;
,这意味着找出一个朋友最喜欢的项目。
我使用命令java -d64 -server -XX:+UseConcMarkSweepGC -XX:+UseNUMA -Xms10752m -Xmx10752m -Xmn2688m -jar Neo4J-1.0-SNAPSHOT.jar
现在,我的实验结果如下: (1)单线程 每个查询平均花费约70毫秒。 (2)8线程 每个查询平均花费约160毫秒,许多查询花费超过500毫秒。 RPS约为50 /秒。
我想提高性能,但不知道如何。看来ram还不足以保存所有数据,是吗? 此外,我已经尝试过柔和且强大的cache_type,当它正在升温时,ram很快就会充满。
请帮助我并教我如何改进它。 非常感谢。
答案 0 :(得分:0)
如果堆大小/可用RAM太小而无法在对象缓存中保存完整数据集,则可以使用企业版。通过在n个Neo4j实例前放置一个负载均衡器,将所有对图形某一部分的请求路由到同一个实例,您基本上就可以进行对象缓存分片。关于这种方法的Jim Webber bloggt:http://jim.webber.name/2011/02/scaling-neo4j-with-cache-sharding-and-neo4j-ha/
对于性能关键型查询,可能需要使用traversal API将Cypher查询重构为等效查询,或者甚至转到核心API。