我正在使用 AWS dynamoDB 本地实施作为 16GB 机器上的存储后端来处理 Titan 1.0。我的用例涉及定期生成包含大约 120K 的顶点和边的图。每次我在内存中生成一个新图形时,我都会检查存储在 DB 中的图形,然后 (i) 添加不存在的顶点/边,或者 (ii) 如果它们已经存在则更新属性(存在由“标签”确定和一个“价值”属性)。请注意,“值”属性已编入索引。事务以 500 个顶点为一批提交。
问题:我发现每次处理新图时这个过程都会变慢(第一个图在 45 分钟内完成,最初是空数据库,第二个花了 2.5 小时,第三个在 3.5 小时内,第四个在 6 小时内,第五个在 10 小时内等等)。事实上,在处理给定的图时,它在开始时相当快,但逐渐变慢(初始批次需要 2-4 秒,后来对于 500 个节点的相同批次大小,它增加到 100 秒;我有时也看到它一批需要 1000-2000 秒)。这只是处理时间(见下面的方法);提交总是需要 8-10 秒。我将 jvm 堆大小配置为 10G,我注意到当应用程序运行时,它最终会用完所有这些。
问题:这种行为是否可以预期?在我看来,这里出了点问题(在我的配置/方法中?)。任何帮助或建议将不胜感激。
方法:
- 从内存图的根节点开始,检索所有子节点并维护一个队列
对于每个子节点,我检查它是否存在于数据库中,否则创建新节点并更新一些属性
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;
}
Schema Def:(显示一些索引)
注意:
“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();
}