用DB> neo4j java查询巨大减速32G

时间:2017-06-29 00:07:13

标签: java performance neo4j

我正在测试不同大小的数据集上的java查询,1亿个到10亿个边缘(每个顶点10个边缘)。 查询不会返回太多数据,10到20个具有相应边的顶点,但需要扫描整个数据集。

当数据库大小超过32 Gigs时,我可以看到性能大幅下降。 我将java堆大小更改为96G并使用垃圾收集器选项(保留-XX:+ UseG1GC作为最改进的选项) 为了获得更好的结果,但我的表现仍然大幅下降:

100M边缘,数据库为7.5G:查询需要12分钟 250M边缘,数据库为19G:35分钟 500M边缘,数据库是38G:12小时使用-XX:+ UseG1GC 1B边缘,数据库是76G:51小时没有-XX:+ UseG1GC

对于5亿和10亿测试,我可以看到大部分操作是系统操作60%,而用户操作40%(来自top linux命令)。当我运行较小的测试时,100%的操作是用户操作。

Neo4j的entreprise版本中的java GC改进是否足以使较大数据集查询的性能与较小的数据集查询的性能相同? 我还能做些什么来改善大型数据集查询的性能吗?

TKS

我在32核244 RAM虚拟服务器上运行所有这些测试。

我还尝试增加页面缓存大小,但我没有看到改进。

用例: 我在数据中搜索模式,查询扫描所有数据集,找到4或5个具有特殊关系模式的节点。

查询在线程中运行,因此所有32个核心同时运行。

我试图改变: - 每个线程的节点数 - 堆大小 - 缓存大小 - GC选项

但改善不大。 这是Java限制吗? 感谢

2 个答案:

答案 0 :(得分:0)

我看到你试图配置JVM堆,但是你在page cache上做了同样的事吗?

JVM的堆用于存储所有事务内容,页面缓存用于存储图形数据以避免磁盘I / O.

我建议您查看此文档(如果尚未完成)页面:https://neo4j.com/docs/operations-manual/3.2/performance/#memory-tuning

让一个高于12Go的Java堆可能导致一些大的GC,因此性能较差。

EE有一些改进,但对于你的具体情况,我不认为差距会有意义。

最后,要使一个需要所有数据的查询在每个数据库系统上都是一个坏主意。我对用例感到好奇。你能解释一下吗?

就像@Jerome所说,你必须调整你的查询。

干杯。

答案 1 :(得分:0)

我不认为调优查询解释了这里的可伸缩性问题,因为查询在较小的数据集(高达2.5亿个关系)中非常有效,并且当它变大时指数速度慢。 Java内存管理必须发挥作用,但我无法找到解决问题的方法。

查询以增加的速度搜索三角形,并且最大和最小速度必须在边距内(50)。该图被简化为在关系(速度)上只有一个参数。 Cypher查询: 匹配(a) - [d] - >(b) - [e] - >(c) - [f] - >(a)其中d.speed< = e.speed AND e.speed< = f.speed AND(f.speed-d.speed)< = 50返回a,b,c。

Java Query在线程中的每个节点上运行:

void findTriangleV1(Node n ){
    Iterable<Relationship> Level1 = n.getRelationships(Direction.OUTGOING);
    for( Relationship r1 : Level1 ) {
        if (r1.getEndNodeId() != n.getId()){
            Integer tsr1 = ( Integer )r1.getProperty( "speed" );
            Iterable<Relationship> Level2 = r1.getEndNode().getRelationships(Direction.OUTGOING);
            for( Relationship r2 : Level2) {
                if (r1.getEndNodeId() != r2.getEndNodeId()){
                    Integer tsr2 = ( Integer )r2.getProperty( "speed" );                                
                    if ((tsr2 >= tsr1) && (tsr2 - tsr1 <= limit)){
                        Iterable<Relationship> Level3 = r2.getEndNode().getRelationships(Direction.OUTGOING);
                        for( Relationship r3 : Level3) {
                            if (r3.getEndNodeId() == n.getId()){
                                Integer tsr3 = ( Integer )r3.getProperty( "speed" );
                                if ((tsr3 >= tsr2) && (tsr3 - tsr1 <= limit)){
                                    System.out.print( "\nV1 FOUND ONE ["+ n.getId() +" - "+ r1.getEndNodeId()+" - "+ r2.getEndNodeId()+"] & ");     
                                    System.out.print( "speed ["+ tsr1 +" - "+ tsr2+" - "+ tsr3+"] \n"); 
                                }                               
                            }
                        }
                    }                   
                }
            }
        }
    }
    return;
}