Performance 移除边缘时Titan性能会提高

Performance 移除边缘时Titan性能会提高,performance,titan,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

以下是我的测试程序,用于测试删除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 顶点v1=g.addVertex(空); int i=0; long lastTime=System.currentTimeMillis(); while(true){ 顶点v2=g.addVertex(空); Iterable Iterable=v1.GetEdge(Direction.IN,“最后数据”); 用于(边e:可编辑){ e、 删除(); } v2.增补(“最后数据”,v1); g、 提交(); 如果(i%100==0){ 长持续时间=(System.currentTimeMillis()-lastTime); System.out.println(“计数:“+String.format(“%7s”,i)+”,持续时间:“+String.format(“%7s”,持续时间)+”ms”); lastTime=System.currentTimeMillis(); }//如果结束,则结束 i++; }//结束时 随着时间的推移,删除边所需的时间越来越长,即使边的数量始终保持为1

这是虫子吗? 由于边数始终为1,删除边所需的时间不应该保持不变吗? 是什么导致了这种行为?
无论如何,解决方法?

当您删除一条边时,它可能会从图形的角度消失,但实际上它会被删除,以便在将来压缩时删除

您的代码正在将边添加到一个现有顶点,即
v1
,(以及每个循环上新创建的顶点),并通过从
v1
中删除边将其删除。这意味着,随着压缩之前删除的边数的增加,您必须读取墓碑数据才能到达最后添加的边

除了执行压缩外,一种替代方法是从相反方向(即从
v2
)删除边缘,或根据其ID删除边缘。这些方法已使我克服了这些问题。具体地讲,假设这是一个现实问题,您正在快速添加/删除超级节点的边,那么某种形式的以顶点为中心的查询可能会有所帮助……例如:

v1.query().limit(1).edges()
不过,这可能会修复您的“测试代码”,您只需尝试一下就可以了。这种方法对我很有效(你可以粘贴到Titan Gremlin REPL中):


在创建的每个
v2
上执行
setProperty
,可以加快降级速度,如下所示:

    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个循环)。

性能下降很可能是由于标记删除以前添加的边缘的墓碑堆积所致。这些仅在下次压实时清除。这就是为什么在Cassandra和BerkeleyJe(处理删除的方式不同)上会出现性能下降的原因

有一些调优选项可以为此类用例获得更好的性能,但从根本上说,这种行为不会消失。
我们正致力于在边缘上支持生存时间标记,允许您指定边缘的过期时间,如果适用,这将是在这种情况下处理删除的一种更具伸缩性的方式。

您使用哪种后端?cassandra?是的,我使用cassandra 2.0.4作为后端存储。卡桑德拉导致了这个问题吗?有趣的是…我不小心让你的程序运行了。到了3米左右的边缘,没有太多的脱脂。有点奇怪。不管怎么说,我的答案仍然站得住脚,因为我以前见过这种行为?你是说3M圈吗?因为我每次循环都会删除边,所以在任何时候都应该有一条边(正如您从图表的角度所说的)。我在i7桌面上运行,我几乎立即看到降级效果(少于10000个循环),我尝试了
v1.query().limit(1.edges(),没有帮助。不是
v1.getEdges(Direction.IN,“last data”)
v1.query().direction(direction.IN).labels(“last data”).edges()相同哪一个是顶点查询?我的意思是3M循环,但我有一个错误的配置,所以我以前的答案是不好的。在@daniel kuppitz的帮助下,我重现了你的问题。正如您所提到的,我开始看到大约10000个循环的性能下降。我已经更新了我的答案,并加入了一个groovy脚本,它最终为我工作。即使使用该模型,我也看到了峰值,但我认为这只是因为cassandra必须刷新提交日志。如果不在循环的每个周期都提交,您可能会做得更好。我已经发布了我的结果。我认为我的测试程序与titan wiki上描述的程序非常相似,但即使每次循环都执行相同的操作,我也无法达到稳定的性能。嘿,Melvin,请分享你的测试结果,这样每个人都知道我们在谈论哪些数字。这是我的5000圈:嗨,丹尼尔和斯蒂芬。我试过伯克利公司的泰坦,嵌入式卡桑德拉和远程卡桑德拉。结果是,连同我的测试程序。嵌入式和远程cassandra的性能似乎都在上升,但berkeleyje却没有。如果是这样,那么在压缩之后,性能不应该恢复正常,但到目前为止,我观察到性能一直在下降。无论如何,谢谢。好的,我从stephen那里了解到压缩是一项管理功能。我认为这是一个周期性的运行时函数。
    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