【问题标题】:Write performance about neo4j when use py2neo使用py2neo时写关于neo4j的性能
【发布时间】:2014-11-07 02:13:50
【问题描述】:

我正在尝试在我的应用程序中使用 neo4j。现在我面临一些关键的问题 实验中的问题。问题陈述分为这样的 几个部分。

背景:

用例是从互联网获取数据,数据规模为十亿, 场景是实时的,关系只是人与人之间的关系 属性。

配置:

机器配置:

  cpu: 24 processors, Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz
  memory: 165 203 696 kB
  jdk: java version "1.7.0_67",  Java(TM) SE Runtime Environment (build 1.7.0_67-b01),  Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
  Linux version: 2.6.32-431.el6.x86_64
  OS: CentOS release 6.5

Neo4j 配置:

  enterprise version: 2.1.5
  jvm heap: default
  objects cache:
  neostore.nodestore.db.mapped_memory=512M
  neostore.relationshipstore.db.mapped_memory=6G
  neostore.propertystore.db.mapped_memory=5G
  neostore.propertystore.db.strings.mapped_memory=1G
  neostore.propertystore.db.arrays.mapped_memory=1G

客户端配置:

  pyneo, version 1.6.4

客户端代码:

CYPHER_WEIGHT_COMPUTE='r.weight=r.weight+r.weight*EXP((TIMESTAMP()-r.update_time)/(r.half_life*1.0))'

// Initiation, create constraints according the label on id
self.query=neo.CypherQuery(self.graph_db,'CREATE CONSTRAINT ON (pn:UID)
ASSERT pn.id IS UNIQUE')
self.query.execute()
self.query=neo.CypherQuery(self.graph_db,'CREATE CONSTRAINT ON (pm:GID)
ASSERT pm.id IS UNIQUE')
self.query.execute()

// Cypher clause
MERGE(first:{TYPE1} {{id:'{val1}'}})
MERGE (second:{TYPE2} {{id:'{val2}'}})
MERGE (first)-[r:{RTYPE}]->(second) ON CREATE SET r.weight={weight_set} ON
MATCH SET {weight_compute}
WITH r
SET r.half_life={half_life},
    r.update_time=TIMESTAMP(),
    r.threshold={threshold}
WITH r
WHERE r.weight<r.threshold
DELETE r

self.query=neo.CypherQuery(self.graph_db,self.create_rels.
     format(TYPE1=entity1[0],val1=entity1[1],
            TYPE2=entity2[0],val2=entity2[1],
            RTYPE=rel_type,weight_set=weight_set,

weight_compute=CYPHER_WEIGHT_COMPUTE,half_life=half_life,threshold=threshold))

结果:

当我使用 24 个 python 线程和 py2neo 写入 59229 个节点时,236048 关系,531325 个属性。平均时间费用约为 1316 秒。结果不能满足我的实时需求,对我来说效果很好 如果时间开销减少到 150 秒。以及每个人的时间费用 节点/关系会随着数据规模的增加而增加

问题:

  1. 除了 优化密码子句并使用批量插入?我试过了 配置不同大小的 jvm 堆和对象缓存的方法。我发现 它对写入性能的影响较小,我认为原因可能是 小规模的节点/关系(从数千到一万), 在大规模节点/关系中效率可能很重要( 一千万,十亿)

  2. neo4j'读写性能可以达到多少nps或rps 您在数十亿节点/关系方面的经验?

  3. 我也发现neo4j不能自动分片,但是有 文档中关于基于缓存的分片的一节,如果我使用基于缓存的分片 使用 HAproxy 分片,节点之间的关系如何 分片到不同的机器维护?也就是说 分片不会破坏关系。

  4. 社区版和企业版都可以使用主/从模式吗?

提前致谢。

问候

【问题讨论】:

  • 您确定节点是使用预期标签创建的吗? AFAIK 你不能参数化标签/reltype。这可能会影响标签约束索引的使用。
  • 我想你的海量数据。我不会使用 cypher,而是使用具有专用端点的服务器扩展来消耗大量数据,然后使用 Neo4j Java API 相应地对插入进行批处理。
  • 嗨迈克尔,我已经这样做了。我想我已经解决了性能问题,但是分片问题现在很关键。由于海量数据、图的连接性和可变性,我们不能使用基于缓存的分片。我想我应该放弃图形数据库。

标签: performance neo4j py2neo


【解决方案1】:
  1. 您必须将这些作为不同的请求执行吗?我建议您使用事务密码端点:http://nigelsmall.com/py2neo/1.6/cypher/#id2

  2. 取决于使用的查询和 API。以及您计算读取和写入的方法。使用事务性 http API,我已经设法获得每秒 30k 的密码创建语句,其中包含两个节点和一个 rel。合并有点慢,你需要确保你使用的是约束索引。

  3. 这个想法是通过允许用户子集(或您可以定义的子集)在特定集群节点上查询来保留缓存的数据子集。如果查询需要遵循的关系没有被缓存,它将最终从磁盘读取。所有数据都必须在集群所有成员的磁盘上。

  4. 我不确定,但我很确定所有集群功能都随企业提供。

【讨论】:

  • 刚刚意识到我的回答略有不同#2。 1B 个节点/rels 应该没问题,你会需要很多内存。
  • 嗨,韦斯,第三个答案我也有一些疑问。假设有一条路径 (a)-(b)-[n..]-(q),其中 n>500。路径中的节点一直在分片到不同机器的缓存,那如何保证节点之间的关系不坏呢?谢谢
  • 我认为你在这个分片缓存概念中缺少的关键是所有数据都必须在所有机器上。缓存包含一个子集,并且在缓存未命中的情况下必须从磁盘读取。
  • 好了,我想我已经知道缓存分片的含义了。但是当数据规模太大以至于无法存储在几台机器上时,它还不能解决问题。由于图的连通性和可变性,也许这个问题实际上是一个 NP-hard 问题
猜你喜欢
  • 2019-04-15
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多