13

私が作成した Michael Hunger の Batch Import を使用してデータをインポートしました:-

4,612,893 nodes
14,495,063 properties
    node properties are indexed.
5,300,237 relationships

{質問} Cypher クエリの実行が遅すぎてほとんどクロールしません。単純なトラバーサルで結果セットを返すのに 5 分以上かかります。パフォーマンスを向上させるためにサーバーを調整する方法と、私が間違っていることを教えてください。

店舗詳細:-

-rw-r--r-- 1 root root 567M Jul 12 12:42 data/graph.db/neostore.propertystore.db
-rw-r--r-- 1 root root 167M Jul 12 12:42 data/graph.db/neostore.relationshipstore.db
-rw-r--r-- 1 root root  40M Jul 12 12:42 data/graph.db/neostore.nodestore.db
-rw-r--r-- 1 root root 7.8M Jul 12 12:42 data/graph.db/neostore.propertystore.db.strings
-rw-r--r-- 1 root root  330 Jul 12 12:42 data/graph.db/neostore.propertystore.db.index.keys
-rw-r--r-- 1 root root  292 Jul 12 12:42 data/graph.db/neostore.relationshiptypestore.db.names
-rw-r--r-- 1 root root  153 Jul 12 12:42 data/graph.db/neostore.propertystore.db.arrays
-rw-r--r-- 1 root root   88 Jul 12 12:42 data/graph.db/neostore.propertystore.db.index
-rw-r--r-- 1 root root   69 Jul 12 12:42 data/graph.db/neostore
-rw-r--r-- 1 root root   58 Jul 12 12:42 data/graph.db/neostore.relationshiptypestore.db
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.nodestore.db.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.propertystore.db.arrays.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.propertystore.db.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.propertystore.db.index.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.propertystore.db.index.keys.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.propertystore.db.strings.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.relationshipstore.db.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.relationshiptypestore.db.id
-rw-r--r-- 1 root root    9 Jul 12 12:42 data/graph.db/neostore.relationshiptypestore.db.names.id

私は使っている

neo4j-community-1.9.1
java version "1.7.0_25"
Amazon EC2 m1.large instance with Ubuntu 12.04.2 LTS (GNU/Linux 3.2.0-40-virtual x86_64)
RAM ~8GB.
EBS 200 GB, neo4j is running on EBS volume.

./neo4j-community-1.9.1/bin/neo4j start として起動

以下は、neo4j サーバー情報です。

neostore.nodestore.db.mapped_memory                 161M
neostore.relationshipstore.db.mapped_memory         714M
neostore.propertystore.db.mapped_memory              90M
neostore.propertystore.db.index.keys.mapped_memory    1M
neostore.propertystore.db.strings.mapped_memory     130M
neostore.propertystore.db.arrays.mapped_memory      130M
mapped_memory_page_size                               1M
all_stores_total_mapped_memory_size                 500M

{データモデル}はソーシャルグラフのようなものです:-

User-User
    User-[:FOLLOWS]->User
User-Item
    User-[:CREATED]->Item
    User-[:LIKE]->Item
    User-[:COMMENT]->Item
    User-[:VIEW]->Item
Cluster-User
    User-[:FACEBOOK]->SocialLogin_Cluster
Cluster-Item
    Item-[:KIND_OF]->Type_Cluster
Cluster-Cluster
    Cluster-[:KIND_OF]->Type_Cluster

{いくつかのクエリ}と時間:

START u=node(467242)
MATCH u-[r1:LIKE|COMMENT]->a<-[r2:LIKE|COMMENT]-lu-[r3:LIKE]-b
WHERE NOT(a=b)
RETURN u,COUNT(b)

クエリには 1015348 ミリ秒かかりました。70956115 の結果カウントが返されました。

START a=node:nodes(kind="user")
RETURN a,length(a-[:CREATED|LIKE|COMMENT|FOLLOWS]-()) AS cnt
ORDER BY cnt DESC
LIMIT 10

クエリに 231613 ミリ秒かかりました


提案から、ボックスを M1.xlarge と M2.2xlarge にアップグレードしました

  • M1.xlarge (vCPU:4,ECU:8,RAM:15GB,インスタンスストレージ:~600GB)
  • M2.2xlarge (vCPU:4,ECU:13,RAM:34GB,インスタンスストレージ:~800GB)

以下のようにプロパティを調整し、インスタンス ストレージから実行しました (EBS に対して)

neo4j.properties

neostore.nodestore.db.mapped_memory=1800M
neostore.relationshipstore.db.mapped_memory=1800M
neostore.propertystore.db.mapped_memory=100M
neostore.propertystore.db.strings.mapped_memory=150M
neostore.propertystore.db.arrays.mapped_memory=10M

neo4j-wrapper.conf

wrapper.java.additional.1=-d64
wrapper.java.additional.1=-server
wrapper.java.additional=-XX:+UseConcMarkSweepGC
wrapper.java.additional=-XX:+CMSClassUnloadingEnabled
wrapper.java.initmemory=4098
wrapper.java.maxmemory=8192

ただし、クエリ (以下のようなもの) は 5 ~ 8 分で実行されますが、これは推奨の観点からは受け入れられません。

クエリ:

START u=node(467242)
MATCH u-[r1:LIKE]->a<-[r2:LIKE]-lu-[r3:LIKE]-b
RETURN u,COUNT(b)

{プロファイリング}

neo4j-sh (0)$ profile START u=node(467242) MATCH u-[r1:LIKE|COMMENT]->a<-[r2:LIKE|COMMENT]-lu-[r3:LIKE]-b RETURN u,COUNT(b);
==> +-------------------------+
==> | u            | COUNT(b) |
==> +-------------------------+
==> | Node[467242] | 70960482 |
==> +-------------------------+
==> 1 row
==> 
==> ColumnFilter(symKeys=["u", "  INTERNAL_AGGREGATEad2ab10d-cfc3-48c2-bea9-be4b9c1b5595"], returnItemNames=["u", "COUNT(b)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=["u"], aggregates=["(  INTERNAL_AGGREGATEad2ab10d-cfc3-48c2-bea9-be4b9c1b5595,Count)"], _rows=1, _db_hits=0)
==>   TraversalMatcher(trail="(u)-[r1:LIKE|COMMENT WHERE true AND true]->(a)<-[r2:LIKE|COMMENT WHERE true AND true]-(lu)-[r3:LIKE WHERE true AND true]-(b)", _rows=70960482, _db_hits=71452891)
==>     ParameterPipe(_rows=1, _db_hits=0)


neo4j-sh (0)$ profile START u=node(467242) MATCH u-[r1:LIKE|COMMENT]->a<-[r2:LIKE|COMMENT]-lu-[r3:LIKE]-b RETURN count(distinct a),COUNT(distinct b),COUNT(*);
==> +--------------------------------------------------+
==> | count(distinct a) | COUNT(distinct b) | COUNT(*) |
==> +--------------------------------------------------+
==> | 1950              | 91294             | 70960482 |
==> +--------------------------------------------------+
==> 1 row
==> 
==> ColumnFilter(symKeys=["  INTERNAL_AGGREGATEe6b94644-0a55-43d9-8337-491ac0b29c8c", "  INTERNAL_AGGREGATE1cfcd797-7585-4240-84ef-eff41a59af33", "  INTERNAL_AGGREGATEea9176b2-1991-443c-bdd4-c63f4854d005"], returnItemNames=["count(distinct a)", "COUNT(distinct b)", "COUNT(*)"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["(  INTERNAL_AGGREGATEe6b94644-0a55-43d9-8337-491ac0b29c8c,Distinct)", "(  INTERNAL_AGGREGATE1cfcd797-7585-4240-84ef-eff41a59af33,Distinct)", "(  INTERNAL_AGGREGATEea9176b2-1991-443c-bdd4-c63f4854d005,CountStar)"], _rows=1, _db_hits=0)
==>   TraversalMatcher(trail="(u)-[r1:LIKE|COMMENT WHERE true AND true]->(a)<-[r2:LIKE|COMMENT WHERE true AND true]-(lu)-[r3:LIKE WHERE true AND true]-(b)", _rows=70960482, _db_hits=71452891)
==>     ParameterPipe(_rows=1, _db_hits=0)

チューニング用の設定とneo4jの起動引数を教えてください。前もって感謝します

4

3 に答える 3

14

データセットを使用して、RAM と CPU がほとんどない私の MacBook Air でこれを実行します。

より多くのメモリ マッピング、GCR キャッシュ、およびキャッシュ用のより多くのヒープを使用すると、私の結果よりもはるかに高速になります。また、クエリでは必ずパラメーターを使用してください。

組み合わせ爆発に陥っています。

パスのすべてのステップで、「times rels」要素/行が一致したサブグラフに追加されます。

たとえば、ここを参照してください: 269268 の一致で終了しますが、81674 の個別の lu しかありません。

問題は、行ごとに次の一致が展開されることです。したがって、サイズを再度制限するためにその中間でdistinctを使用すると、データが数桁少なくなります。次のレベルでも同じです。

START u=node(467242)
MATCH u-[:LIKED|COMMENTED]->a
WITH distinct a
MATCH a<-[r2:LIKED|COMMENTED]-lu
RETURN count(*),count(distinct a),count(distinct lu);

+---------------------------------------------------+
| count(*) | count(distinct a) | count(distinct lu) |
+---------------------------------------------------+
| 269268   | 1952              | 81674              |
+---------------------------------------------------+
1 row

895 ms

START u=node(467242)
MATCH u-[:LIKED|COMMENTED]->a
WITH distinct a
MATCH a<-[:LIKED|COMMENTED]-lu
WITH distinct lu
MATCH lu-[:LIKED]-b
RETURN count(*),count(distinct lu), count(distinct b)
;
+---------------------------------------------------+
| count(*) | count(distinct lu) | count(distinct b) |
+---------------------------------------------------+
| 2311694  | 62705              | 91294             |
+---------------------------------------------------+

ここでは、合計 230 万の一致と 91,000 の異なる要素しかありません。したがって、ほぼ2桁です。

これは、OLTP クエリよりもむしろ BI/統計クエリである巨大な集計です。通常、ユーザーノードなどに結果を保存し、これをバックグラウンドで再実行するだけです。

これらの種類のクエリは、グローバル グラフ クエリ (統計/BI) であり、この場合は上位 10 人のユーザーです。

通常、これらをバックグラウンドで (たとえば、1 日または 1 時間に 1 回) 実行し、上位 10 個のユーザー ノードを特別なノードまたはインデックスに接続し、数ミリ秒でクエリを実行します。

START a=node:nodes(kind="user") RETURN count(*);
+----------+
| count(*) |
+----------+
| 3889031  |
+----------+
1 row

27329 ms

結局、グラフ全体、つまり、グラフ ローカル クエリではなく、グラフ グローバルである 400 万人のユーザーに対して一致を実行しています。

START n=node:nodes(kind="top-user")
MATCH n-[r?:TOP_USER]-()
DELETE r
WITH distinct n
START a=node:nodes(kind="user")
MATCH a-[:CREATED|LIKED|COMMENTED|FOLLOWS]-()
WITH n, a,count(*) as cnt
ORDER BY cnt DESC
LIMIT 10
CREATE a-[:TOP_USER {count:cnt} ]->n;

+-------------------+
| No data returned. |
+-------------------+
Relationships created: 10
Properties set: 10
Relationships deleted: 10

70316 ms

クエリは次のようになります。

START n=node:nodes(kind="top-user")
MATCH n-[r:TOP_USER]-a
RETURN a, r.count
ORDER BY r.count DESC;

+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| a                                                                                                                                                  | r.count |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
….
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
10 rows

4 ms
于 2013-07-31T12:21:59.740 に答える
5

わかりました、まず第一に、非常に大きなグラフであるわずか 8GB のメモリについてです。より大きなボックスを入手することを真剣に検討する必要があります。実際、Neo4j は非常に優れたハードウェア計算機を提供しており、ニーズに何が適切かを正確に判断できます。

http://neotechnology.com/calculatorv2/

不自然な方法で (サイズを決定するためにより関連するメトリックがあるため)、彼らの計算機の見積もりは、少なくとも約 10 GB を専用にする必要があります。

第二に、Neo4j と任意のグラフ データベースでは、多数の接続を持つノードで問題が発生します。(より大きなボックスを取得した後に) インスタンスのパフォーマンスを向上させるように調整する場合は、パフォーマンスに深刻な影響を与えるため、多数の接続を持つ大規模なノードを探すことをお勧めします。

あなたの例を見た後、他のノードよりもはるかに多くの接続を持つ多くのノードを持つグラフがあると確信しています。これにより、本質的にパフォーマンスが低下します。より狭いクエリを試すこともできます。特に、小さすぎるサーバーで既に作業している場合は、そこにある非常に負担の大きい大規模なリターン クエリを実行したくありません。

クリーンアップできるクエリがいくつかありますが、グラフに適切なサイズのボックスを取得し、最も接続されているノードの接続数を実際に内省することを強くお勧めします。

また、Java ヒープ サイズに人為的な上限があるようです。次のようなコマンドでJavaを起動しようとすると:

java -Xmx8g //Other stuff

標準の最大 500 メガバイトの代わりに 8 ギガを割り当てることもできます。

于 2013-07-15T19:10:20.463 に答える
1

あなたは必要ありません:

WHERE NOT(a=b)

2 つの異なる識別子がパターン マッチャー内の同じノードになることはありません。

profileクエリで使用できますか?

profile START u=node(467242)
MATCH u-[r1:LIKE|COMMENT]->a<-[r2:LIKE|COMMENT]-lu-[r3:LIKE]-b
RETURN u,COUNT(b)

触れられているノードの数を確認することも興味深いでしょう:

profile START u=node(467242)
MATCH u-[r1:LIKE|COMMENT]->a<-[r2:LIKE|COMMENT]-lu-[r3:LIKE]-b
RETURN count(distinct a),COUNT(distinct b),COUNT(*)

MMIO 設定を実際の値に減らすこともできます。

neostore.nodestore.db.mapped_memory=180M
neostore.relationshipstore.db.mapped_memory=750M

マシンのすべての RAM をヒープとして宣言すると、FS バッファーおよび mmio バッファーと競合します。

wrapper.java.initmemory=5000
wrapper.java.maxmemory=5000

クエリの最初の実行またはその後の実行を測定していますか?

于 2013-07-21T13:56:03.407 に答える