2016-07-29 78 views
1

我在Neo4j有一个奇怪的问题。我最近一直在使用GraphAware TimeTree,并且直到昨天才开始工作。我不得不重建树,因为我犯了一个错误,所以我留下了一个脚本过夜(nohup)。neo4j时间树会被冻结的原因是什么?

今天回来,我发现我的脚本只跑了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万个节点放入我的db中,而单独调用match语句运行得非常好。我甚至还为此唯一属性设置了索引(请参阅上面的架构调用)。

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

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

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

我唯一的想法是,我一直在调用cypher语句并在提交这么多次之前取消它们,无论是通过python还是通过cmd行shell工具。是否有可能在交易管理器完成之前通过取消大交易来搞乱交易管理器?

例如:

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

然后打control-C它运行约2小时后没有完成。


UPDATE:

好了,所以我调查我的日志文件,并发现了一些问题。看起来我的线程由于没有足够的内存而被阻塞。我想我的最大堆大小受到人为限制,并且没有使用我机器上的可用资源。 (也许??)。所以我手动设置dbms.memory.heap.max_size=16000

现在问题似乎消失了!我想我很困惑,因为我期望Java OOM出现在neo4j-shell工具的响应中,而不是像进行中那样闲置。

回答

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; 
> ' 

此查询有多少个节点需要附加到timetree?

此过程不使用批处理,因此它仅限于您的内存在单个事务中可以执行的操作(现在我们正在积压)。

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

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

以这种方式,重新连接完整的数据库(或只有配置为附件的节点)将是重新启动数据库的问题,并且此过程将与批处理事务一起运行,这将显着加快所花费的时间。

+0

这恰好匹配1或0个节点。在这个特定的情况下,它匹配1,因为我用这个'meta_id'进入了db节点。 我以编程方式一次一个地调用此调用,因为试图匹配我的整个记录​​集合的时间过长,而我现在只进行测试。 我确实遇到过自动附件,但还没有看过它。我想这会是一个更好的选择。 另外 - 我想我只是解决了我的问题 - 见上文。 – spanishgum

+0

好的。你能和我们分享你的分贝吗?任何日志也可以分享从数据库? –

+0

很酷,很高兴听到! –