neo4j时间树冻结的原因是什么?

时间:2016-07-29 17:34:44

标签: neo4j graphaware

我在Neo4j遇到了一个奇怪的问题。我最近一直在使用GraphAware TimeTree并且填充它直到昨天才开始。由于我犯了一个错误,我不得不重建树,所以我让脚本一夜之间运行(nohup)。

今天回来,我发现我的剧本只运行了3分钟!

$ ps aux | grep timetreepop
root     21840  0.0  0.0 195952  2816 ?        S    Jul28   0:00 sudo nohup python timetreepop.py
root     21841  0.0  0.2 381416 75016 ?        S    Jul28   0:03 python timetreepop.py

我在工作的时候注意到了这种行为,但是我想把它留在一夜之间,而我不活跃会有所帮助。如果可能存在争用,我也关闭了我的其他java服务器进程。在这一点上,我的服务器只会在后台运行一个python龙卷风服务器,这个服务器不是很大,而且流量不大(每天都有一对一次点击)。

总而言之,我的系统中有足够的可用RAM,CPU没有在其他地方使用,并且我的机器上没有其他进程运行大量IO。使用top / atop可以显示包含可用资源的健康系统。

以下是我的脚本正在做的高级别:

neo = neopop.handler()
for i, meta_id in enumerate(meta_gen(ship='KAOU')):
   neo.populate_timetree(record=meta_id)

我的处理程序在__init__构造函数中创建驱动程序和会话:

self.driver = graphdb.driver(config.NEO4J_HTTP_LINK)
self.session = self.driver.session()

我的生成器提供meta_id个值,这些值是我图表中节点的唯一属性值。

populate_timetree()函数创建以下语句:

MATCH (r:record {meta:"KAQP_20120101v20001_0001"}) WITH r 
CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
YIELD node RETURN node.meta;

一切都工作得很好我第一次去。搞乱我的时间值后,我删除了数据库,重新启动,然后再次尝试。只有这一次,当我打电话关闭会话时,我的程序会冻结:

neo.session.close()

注意:我实际上是在我的__del__解构器中调用它(我知道它可能被认为是不好的做法,但它到目前为止一直在为我工作并且符合我的需要。)

我已经仔细检查了我的所有代码中的流氓readline语句/任何可能导致它暂停的代码。还重新编译了包含所有这些代码的包。我知道事实是它被卡在session.close()声明中。

所以我尝试使用Neo4j-shell工具来查看是否有任何不同。 首先是快速响应检查:

$ neoc 'schema'
Indexes
  ON :record(meta) ONLINE (for uniqueness constraint) 

Constraints
  ON (record:record) ASSERT record.meta IS UNIQUE

好的一切都好。现在我尝试使用timetree调用单个值:

$ ./neo4j-shell -c '
> MATCH (r:record {meta:"KAOU_20110613v20001_0000"}) WITH r 
> CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
> YIELD node RETURN node.meta;
> '

BOOM。 Neo4j卡住了!为了清楚起见,我知道MATCH语句并没有永远在这里,因为这次我只在我的数据库中输入了大约200万个节点,并且单独调用match语句运行得非常好。我甚至为这个唯一属性设置了索引(参见上面的模式调用)。

那么这里发生了什么?我认为如果我只插入一个节点,那么树的初始创建不应该是一个太大的问题。我的第一次尝试似乎完美无瑕。我不确定这次我做了多少不同的事情,除了用我拥有的5800万条记录中的200万填充我的数据库。 (所以它应该更快)。

我实际上让这个命令运行了几个小时,它也只在我的系统上运行了几分钟。我对这里发生的事情感到很困惑。有没有人有任何想法?无论如何我能看到neo4j正在积极地做这个命令吗? (请记住我正在使用社区版)

我正在运行neo4j的3.0.3版本,3.0.3.39 timetree / graphaware和CentOS 7服务器。

我唯一的想法是,我一直在调用cypher语句并在它们提交之前取消它们,无论是通过python还是cmd行shell工具。是否有可能通过在大交易结束前取消大交易而过多地搞乱交易经理?

例如:

/neo4j-shell -c 'MATCH (r:record) CALL ga.timetree.events.attach(....) ....'

然后在control-C运行约2小时后点击dbms.memory.heap.max_size=16000而没有完成。

更新:

好的,所以我调查了我的日志文件并发现了一些问题。由于没有足够的内存,我的线程似乎被阻止了。我想我的最大堆大小是人为限制的,而不是使用我机器上的可用资源。 (也许??)。所以我手动设置neo4j-shell

问题似乎现在消失了!我想我很困惑,因为我希望Java OOM出现在{{1}}工具的响应中而不是空转,就像取得进展一样。

1 个答案:

答案 0 :(得分:1)

$ ./neo4j-shell -c '
> MATCH (r:record {meta:"KAOU_20110613v20001_0000"}) WITH r 
> CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
> YIELD node RETURN node.meta;
> '

此查询预计会将多少个节点附加到时间树?

此程序不使用批处理,因此它仅限于您的记忆在单个事务中可以执行的操作(现在在我们的待办事项中)。

也就是说,手动将事件附加到树上通常没有意义,这个过程是为了方便,但我们建议使用自动事件附件:

https://github.com/graphaware/neo4j-timetree#automatic-event-attachment

通过这种方式,重新附加完整数据库(或仅配置为附件的节点)将重新启动数据库,此过程将与批处理事务一起运行,这将显着加快所需的时间。