以下是我在Titan中删除边缘时测试性能的测试程序:
Vertex v1 = g.addVertex( null ); int i = 0; long lastTime = System.currentTimeMillis(); while ( true ) { Vertex v2 = g.addVertex( null ); Iterable iterable = v1.getEdges( Direction.IN, "last-data" ); for( Edge e : iterable ) { e.remove(); } v2.addEdge( "last-data", v1 ); g.commit(); if ( i % 100 == 0 ) { long duration = ( System.currentTimeMillis() - lastTime ); System.out.println( "count:" + String.format( "%7s", i ) + ", duration:" + String.format( "%7s", duration ) + "ms"); lastTime = System.currentTimeMillis(); } // end if i++; } // end while
随着时间的推移,即使边缘数始终为1,移除边缘所需的时间也会越来越长。
这是一个错误吗? 由于边缘数始终为1,因此移除边缘所需的时间不应该保持不变吗? 是什么导致这种行为? 无论如何解决方法?
答案 0 :(得分:0)
当您移除边缘时,它可能会从图形的角度消失,但实际上它会在未来的压缩中被删除。
您的代码正在向一个现有顶点添加边,即v1
(以及每个循环上新创建的顶点),并通过从v1
删除边来删除它。这意味着随着在压缩之前删除边缘的数量增加,您将被迫读取逻辑删除数据以获得最后添加的边缘。
除了执行压缩之外,一种替代方法是从相反方向删除边(即从v2
)或通过其ID删除边。这些方法让我解决了这些问题。鉴于你的代码是专门的,假设这是一个现实世界的问题,你正在快速添加/删除超级节点的边缘,那么某种形式的以顶点为中心的查询可能有帮助......如:
v1.query().limit(1).edges()
可能会修复您的测试代码"但是,你必须试着去看看。这种方法适合我(你可以粘贴到Titan Gremlin REPL):
g = TitanFactory.open('conf/titan-cassandra.properties')
v1 = g.addVertex(null)
bytes = new byte[ 65536 ]
Arrays.fill( bytes, (byte) 0 )
i = 0;
lastTime = System.currentTimeMillis();
toRemove = null
while ( true ) {
def v2 = g.addVertex( null );
v2.setProperty('b',bytes)
if (toRemove != null) toRemove.remove()
toRemove = v2.addEdge( "last-data", v1 );
g.commit();
if ( i % 100 == 0 ) {
def duration = ( System.currentTimeMillis() - lastTime );
println "count:" + String.format( "%7s", i ) + ", duration:" + String.format( "%7s", duration ) + "ms"
lastTime = System.currentTimeMillis();
} // end if
i++;
}
答案 1 :(得分:0)
在每个setProperty
创建的v2
上,降级速度可以加快,如下所示:
byte[] bytes = new byte[ 65536 ];
Arrays.fill( bytes, (byte) 0 );
Vertex v1 = g.addVertex( null );
Edge pE = null;
int i = 0;
long lastTime = System.currentTimeMillis();
while ( true ) {
Vertex v2 = g.addVertex( null );
v2.setProperty( "chunk", bytes );
if ( pE != null ) {
pE.remove();
}
pE = v2.addEdge( "last-data", v1 );
g.commit();
if ( i % 1000 == 0 ) {
long duration = ( System.currentTimeMillis() - lastTime );
System.out.println( "count:" + String.format( "%7s", i ) + ", duration:" + String.format( "%7s", duration ) + "ms" );
lastTime = System.currentTimeMillis();
} // end if
i++;
} // end while
即使我保持前一个边缘pE
,性能仍会攀升,但速度较慢(少于50000个循环)。
答案 2 :(得分:0)
性能下降很可能是由于标记删除先前添加的边缘的墓碑堆积造成的。这些只会在下一次压缩时清除。这就是为什么你看到Cassandra的表现受到打击而BerkeleyJe(不同地处理删除)的表现不那么好。
有一些调整选项可以为这些用例获得更好的性能,但从根本上说,这种行为不会消失。 我们正在努力支持边缘上的生存时间标记,这将允许您指定边缘的到期时间,如果适用,这将是一种更具可扩展性的方法来处理此类上下文中的删除。