AWS dynamoDB ローカル実装を 16GB マシンのストレージ バックエンドとして使用して、titan 1.0 を使用しています。私の使用例では、頂点とエッジを 120K のオーダーで定期的に含むグラフを生成します。メモリ内に新しいグラフを生成するたびに、DB に保存されているグラフをチェックし、(i) 存在しない頂点/エッジを追加するか、(ii) 既に存在する場合はプロパティを更新します (存在は「ラベル」によって決定されます)。および「値」属性)。'Value' プロパティがインデックス化されていることに注意してください。トランザクションは 500 個の頂点のバッチでコミットされます。
問題:新しいグラフを処理するたびに、このプロセスが遅くなることがわかりました (最初のグラフは最初に空のデータベースで 45 分で終了し、2 番目は 2.5 時間、3 番目は 3.5 時間、4 番目は 6 時間、5 番目は 10 時間など) )。実際、特定のグラフを処理するとき、開始時はかなり高速ですが、徐々に遅くなります (最初のバッチは 2 ~ 4 秒かかり、その後、500 ノードの同じバッチ サイズで数百秒に増加します。バッチには 1000 ~ 2000 秒かかります)。これは処理時間だけです (以下のアプローチを参照)。コミットには常に 8 ~ 10 秒かかります。jvm ヒープ サイズを 10G に設定しましたが、アプリが実行されているときに、最終的にすべてを使い果たしていることに気付きました。
質問:この動作は予期されたものですか? ここで何かが間違っているようです(私の設定/アプローチのどちらかですか?)。どんな助けや提案も大歓迎です。
アプローチ:
- インメモリ グラフのルート ノードから開始して、すべての子ノードを取得し、キューを維持します。
子ノードごとに、DB に存在するかどうかを確認し、存在しない場合は新しいノードを作成し、いくつかのプロパティを更新します。
Vertex dbVertex = dbgraph.traversal().V() .has(currentVertexInMem.label(), "Value", (String) currentVertexInMem.value("Value")) .tryNext() .orElseGet(() -> createVertex(dbgraph, currentVertexInMem)); if (dbVertex != null) { // Update Properties updateVertexProperties(dbgraph, currentVertexInMem, dbVertex); } // Add edge if necessary if (parentDBVertex != null) { GraphTraversal<Vertex, Edge> edgeIt = graph.traversal().V(parentDBVertex).outE() .has("EdgeProperty1", eProperty1) // eProperty1 is String input parameter .has("EdgeProperty2", eProperty2); // eProperty2 is Long input parameter Boolean doCreateEdge = true; Edge e = null; while (edgeIt.hasNext()) { e = edgeIt.next(); if (e.inVertex().equals(dbVertex)) { doCreateEdge = false; break; } if (doCreateEdge) { e = parentDBVertex.addEdge("EdgeLabel", dbVertex, "EdgeProperty1", eProperty1, "EdgeProperty2", eProperty2); } e = null; it = null; } ... if ((processedVertexCount.get() % 500 == 0) || processedVertexCount.get() == verticesToProcess.get()) { graph.tx().commit(); }
関数の作成:
public static Vertex createVertex(Graph graph, Vertex clientVertex) {
Vertex newVertex = null;
switch (clientVertex.label()) {
case "Label 1":
newVertex = graph.addVertex(T.label, clientVertex.label(), "Value",
clientVertex.value("Value"),
"Property1-1", clientVertex.value("Property1-1"),
"Property1-2", clientVertex.value("Property1-2"));
break;
case "Label 2":
newVertex = graph.addVertex(T.label, clientVertex.label(), "Value",
clientVertex.value("Value"), "Property2-1",
clientVertex.value("Property2-1"),
"Property2-2", clientVertex.value("Property2-2"));
break;
default:
newVertex = graph.addVertex(T.label, clientVertex.label(), "Value",
clientVertex.value("Value"));
break;
}
return newVertex;
}
スキーマ定義: (いくつかのインデックスを表示)
注:
"EdgeLabel" = Constants.EdgeLabels.Uses
"EdgeProperty1" = Constants.EdgePropertyKeys.EndpointId
"EdgeProperty2" = Constants.EdgePropertyKeys.Timestamp
public void createSchema() {
// Create Schema
TitanManagement mgmt = dbgraph.openManagement();
mgmt.set("cache.db-cache",true);
// Vertex Properties
PropertyKey value = mgmt.getPropertyKey(Constants.VertexPropertyKeys.Value);
if (value == null) {
value = mgmt.makePropertyKey(Constants.VertexPropertyKeys.Value).dataType(String.class).make();
mgmt.buildIndex(Constants.GraphIndexes.ByValue, Vertex.class).addKey(value).buildCompositeIndex(); // INDEX
}
PropertyKey shapeSet = mgmt.getPropertyKey(Constants.VertexPropertyKeys.ShapeSet);
if (shapeSet == null) {
shapeSet = mgmt.makePropertyKey(Constants.VertexPropertyKeys.ShapeSet).dataType(String.class).cardinality(Cardinality.SET).make();
mgmt.buildIndex(Constants.GraphIndexes.ByShape, Vertex.class).addKey(shapeSet).buildCompositeIndex();
}
...
// Edge Labels and Properties
EdgeLabel uses = mgmt.getEdgeLabel(Constants.EdgeLabels.Uses);
if (uses == null) {
uses = mgmt.makeEdgeLabel(Constants.EdgeLabels.Uses).multiplicity(Multiplicity.MULTI).make();
PropertyKey timestampE = mgmt.getPropertyKey(Constants.EdgePropertyKeys.Timestamp);
if (timestampE == null) {
timestampE = mgmt.makePropertyKey(Constants.EdgePropertyKeys.Timestamp).dataType(Long.class).make();
}
PropertyKey endpointIDE = mgmt.getPropertyKey(Constants.EdgePropertyKeys.EndpointId);
if (endpointIDE == null) {
endpointIDE = mgmt.makePropertyKey(Constants.EdgePropertyKeys.EndpointId).dataType(String.class).make();
}
// Indexes
mgmt.buildEdgeIndex(uses, Constants.EdgeIndexes.ByEndpointIDAndTimestamp, Direction.BOTH, endpointIDE,
timestampE);
}
mgmt.commit();
}