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 tornado サーバーのみを実行していましたが、これはそれほど重くなく、トラフィックも多くありません (1 日に数ヒット)。
全体として、システムには利用可能な 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;
> '
ブーム。Neo4j が動かなくなった! 明確にするために、ここで MATCH ステートメントが永遠にかかるわけではないことを知っています。これは、今回はデータベースに約 200 万ノードしか入れておらず、match ステートメントだけを呼び出すだけでまったく問題なく実行されるためです。この一意のプロパティのインデックスも設定しています (上記のスキーマ呼び出しを参照)。
それで、ここで何が起こっているのですか?単一のノードのみを挿入する場合、ツリーの最初の作成はそれほど問題にならないと思います。私の最初の試みは完璧に実行されているようです。私が持っていた 5,800 万件のレコードのうち 200 万件をデータベースに入力することを除いて、今回は何が違うのかわかりません。(したがって、はるかに高速になるはずです)。
実際、このコマンドを数時間実行したままにしましたが、私のシステムでは数分間しか実行されていませんでした。ここで何が起こっているのか、私はとても混乱しています。誰にもアイデアはありますか?とにかく、neo4jがこのコマンドについて積極的に行っていることを確認できますか? (コミュニティエディションを使用していることに注意してください)
私はneo4jのバージョン3.0.3と、CentOS 7サーバーで3.0.3.39 timetree / graphawareを実行しています。
私が持っている唯一の考えは、それがpythonまたはcmdラインシェルツールを介しているかどうかにかかわらず、サイファーステートメントを呼び出して、コミットする前にそれらをキャンセルしてきたということです。大きなトランザクションが完了する前にキャンセルして、トランザクション マネージャーをいじりすぎている可能性はありますか?
例えば:
/neo4j-shell -c 'MATCH (r:record) CALL ga.timetree.events.attach(....) ....'
そしてcontrol-C
2時間ほど走りきってからヒット。
アップデート:
わかりましたので、ログ ファイルを調査したところ、いくつかの問題が見つかりました。十分なメモリがないためにスレッドがブロックされていたようです。私の最大ヒープサイズは人為的に制限されており、マシンで利用可能なリソースを使用していなかったと思います. (多分??)。だから私は手動で設定しdbms.memory.heap.max_size=16000
ました。
問題は解決したようです。neo4j-shell
Java OOM がツールの応答に表示されることを期待していたので、私は混乱していたと思います。