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

What are reasons why the neo4j time tree would be freezing up?

我在 Neo4j 中遇到了 st运行ge 问题。我最近一直在使用 GraphAware TimeTree 并且填充它直到昨天都很顺利。由于我犯了一个错误,我不得不重建树,所以我留下了一个脚本 运行ning 过夜(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

好的,一切顺利。现在我尝试对单个值调用时间树:

$ ./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;
> '

轰隆隆。 Neo4j 卡住了!需要明确的是,我知道 MATCH 语句在这里不会永远占用,因为这次我只将大约 200 万个节点放入我的数据库中,并且单独调用匹配语句 运行 绝对没问题。我什至为这个唯一的属性设置了一个索引(参见上面的模式调用)。

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

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

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

我唯一的想法是,无论是通过 python 还是命令行 shell 工具,我一直在多次调用密码语句并在它们提交之前取消它们。有没有可能我在 t运行saction 管理器完成之前取消大的 t运行saction 太麻烦了?

例如:

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

然后在 运行s 之后点击 control-C 大约 2 小时没有完成。


更新:

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

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

$ ./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

这样,重新附加完整的数据库(或仅为附加配置的节点)将是重新启动数据库的问题,并且此过程将 运行 使用批处理事务,这将加快显着增加所花费的时间。