去除边缘时Titan性能会提高

时间:2014-04-09 02:01:13

标签: performance titan

以下是我在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,因此移除边缘所需的时间不应该保持不变吗? 是什么导致这种行为? 无论如何解决方法?

3 个答案:

答案 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(不同地处理删除)的表现不那么好。

有一些调整选项可以为这些用例获得更好的性能,但从根本上说,这种行为不会消失。 我们正在努力支持边缘上的生存时间标记,这将允许您指定边缘的到期时间,如果适用,这将是一种更具可扩展性的方法来处理此类上下文中的删除。