【问题标题】:Gremlin Spark Java Maven Project - Slow query responseGremlin Spark Java Maven 项目 - 查询响应慢
【发布时间】:2020-10-25 21:59:56
【问题描述】:

我编写了一个程序,以便在 Spark 的帮助下在 Gremlin 之上执行一些查询(我使用带有 Cassandra 和 Solr 作为引擎的 Janus Graph),但是查询结果非常慢。

很可能我的设置不正确。

这是我使用的代码。

驱动程序:

import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.spark.process.computer.SparkGraphComputer;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;

public class SimpleApp {


    public static void main(String[] args) throws Exception {

        Configuration config = GraphTraversalProvider.makeLocal();
        Graph hadoopGraph = GraphFactory.open(config);


        Long totalVertices = hadoopGraph.traversal().withComputer(SparkGraphComputer.class).V().count().next();
        System.out.println("IT WORKED: " + totalVertices);


        hadoopGraph.close();

    }
}

GraphTraversalProvider 类

import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.hadoop.Constants;

public class GraphTraversalProvider {

    private static final String KEY_SPACE = "janusgraph";
    private static final String CASSANDRA_ADDRESS = "localhost";

    public static Configuration makeLocal() {
        return make(true);
    }

    public static Configuration makeRemote() {
        return make(false);
    }

    private static Configuration make(boolean local) {

        final Configuration hadoopConfig = new BaseConfiguration();

        hadoopConfig.setProperty("gremlin.graph", "org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph");
        hadoopConfig.setProperty(Constants.GREMLIN_HADOOP_GRAPH_READER, "org.janusgraph.hadoop.formats.cql.CqlInputFormat");
        hadoopConfig.setProperty(Constants.GREMLIN_HADOOP_GRAPH_WRITER, "org.apache.hadoop.mapreduce.lib.output.NullOutputFormat");

        hadoopConfig.setProperty(Constants.GREMLIN_HADOOP_JARS_IN_DISTRIBUTED_CACHE, true);
        hadoopConfig.setProperty(Constants.GREMLIN_HADOOP_INPUT_LOCATION, "none");
        hadoopConfig.setProperty(Constants.GREMLIN_HADOOP_OUTPUT_LOCATION, "output");
        hadoopConfig.setProperty(Constants.GREMLIN_SPARK_PERSIST_CONTEXT, true);


        hadoopConfig.setProperty("janusgraphmr.ioformat.conf.storage.backend", "cql");
        hadoopConfig.setProperty("janusgraphmr.ioformat.conf.storage.hostname", CASSANDRA_ADDRESS);
        hadoopConfig.setProperty("janusgraphmr.ioformat.conf.storage.port", "9042");
        hadoopConfig.setProperty("janusgraphmr.ioformat.conf.storage.cassandra.keyspace", KEY_SPACE);


        hadoopConfig.setProperty("cassandra.input.partitioner.class", "org.apache.cassandra.dht.Murmur3Partitioner");
        hadoopConfig.setProperty("cassandra.input.widerows", true);

        if (local) {
            hadoopConfig.setProperty("spark.master", "local[*]"); // Run Spark locally with as many worker threads as logical cores on your machine.
        } else {
            hadoopConfig.setProperty("spark.master", "spark://ADD_YOUR_URL");
        }
        hadoopConfig.setProperty("spark.executor.memory", "2g");
        hadoopConfig.setProperty(Constants.SPARK_SERIALIZER, "org.apache.spark.serializer.KryoSerializer");
        hadoopConfig.setProperty("spark.kryo.registrator", "org.janusgraph.hadoop.serialize.JanusGraphKryoRegistrator");


        hadoopConfig.setProperty("storage.hostname", CASSANDRA_ADDRESS);
        hadoopConfig.setProperty("storage.cassandra.keyspace", KEY_SPACE);


        return hadoopConfig;
    }


}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ibc</groupId>
    <artifactId>sparkdemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <janus.version>0.5.1</janus.version>
        <spark.version>2.4.0</spark.version>
        <gremlin.version>3.4.6</gremlin.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>

        <dependency>
            <groupId>org.janusgraph</groupId>
            <artifactId>janusgraph-cassandra</artifactId>
            <version>${janus.version}</version>
        </dependency>

        <dependency>
            <groupId>org.janusgraph</groupId>
            <artifactId>janusgraph-hadoop</artifactId>
            <version>${janus.version}</version>
        </dependency>

        <dependency>
            <groupId>org.janusgraph</groupId>
            <artifactId>janusgraph-cql</artifactId>
            <version>${janus.version}</version>
        </dependency>

        <dependency>
            <groupId>org.janusgraph</groupId>
            <artifactId>janusgraph-solr</artifactId>
            <version>${janus.version}</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- GREMLIN -->
        <dependency>
            <groupId>org.apache.tinkerpop</groupId>
            <artifactId>spark-gremlin</artifactId>
            <version>${gremlin.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.tinkerpop</groupId>
            <artifactId>hadoop-gremlin</artifactId>
            <version>${gremlin.version}</version>
        </dependency>

        <!-- SPARK -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>${spark.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>



    </dependencies>


</project>

输出如下:


23:36:29,708 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to WARN
23:36:29,708 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [CONSOLE] to Logger[ROOT]
23:36:29,708 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
23:36:29,710 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@704d6e83 - Registering current configuration as safe fallback point

SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
23:36:30.225 [main] WARN  o.a.t.g.s.p.c.SparkGraphComputer - class org.apache.hadoop.mapreduce.lib.output.NullOutputFormat does not implement PersistResultGraphAware and thus, persistence options are unknown -- assuming all options are possible
23:36:30.516 [SparkGraphComputer-boss] WARN  org.apache.spark.util.Utils - Your hostname, nchristidis-GL502VMK resolves to a loopback address: 127.0.1.1; using 192.168.1.12 instead (on interface wlp3s0)
23:36:30.516 [SparkGraphComputer-boss] WARN  org.apache.spark.util.Utils - Set SPARK_LOCAL_IP if you need to bind to another address
23:36:32.191 [SparkGraphComputer-boss] WARN  o.a.hadoop.util.NativeCodeLoader - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
23:36:33.279 [SparkGraphComputer-boss] WARN  o.a.t.g.s.p.c.SparkGraphComputer - HADOOP_GREMLIN_LIBS is not set -- proceeding regardless
23:36:35.266 [SparkGraphComputer-boss] WARN  com.datastax.driver.core.NettyUtil - Found Netty's native epoll transport in the classpath, but epoll is not available. Using NIO instead.

IT WORKED: 43
23:39:32.111 [Thread-3] WARN  org.apache.spark.SparkContext - Ignoring Exception while stopping SparkContext from shutdown hook
java.lang.NoSuchMethodError: io.netty.bootstrap.ServerBootstrap.config()Lio/netty/bootstrap/ServerBootstrapConfig;
    at org.apache.spark.network.server.TransportServer.close(TransportServer.java:154)
    at org.apache.spark.network.netty.NettyBlockTransferService.close(NettyBlockTransferService.scala:180)
    at org.apache.spark.storage.BlockManager.stop(BlockManager.scala:1615)
    at org.apache.spark.SparkEnv.stop(SparkEnv.scala:90)
    at org.apache.spark.SparkContext$$anonfun$stop$11.apply$mcV$sp(SparkContext.scala:1974)
    at org.apache.spark.util.Utils$.tryLogNonFatalError(Utils.scala:1340)
    at org.apache.spark.SparkContext.stop(SparkContext.scala:1973)
    at org.apache.spark.SparkContext$$anonfun$2.apply$mcV$sp(SparkContext.scala:575)
    at org.apache.spark.util.SparkShutdownHook.run(ShutdownHookManager.scala:216)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(ShutdownHookManager.scala:188)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply(ShutdownHookManager.scala:188)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply(ShutdownHookManager.scala:188)
    at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1945)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply$mcV$sp(ShutdownHookManager.scala:188)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply(ShutdownHookManager.scala:188)
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply(ShutdownHookManager.scala:188)
    at scala.util.Try$.apply(Try.scala:192)
    at org.apache.spark.util.SparkShutdownHookManager.runAll(ShutdownHookManager.scala:188)
    at org.apache.spark.util.SparkShutdownHookManager$$anon$2.run(ShutdownHookManager.scala:178)
    at org.apache.hadoop.util.ShutdownHookManager$1.run(ShutdownHookManager.java:54)

Process finished with exit code 123

所以我得到了正确的输出:IT WORKED: 43 43 是总顶点,但需要的时间太长。

还有这条日志消息:

23:36:33.279 [SparkGraphComputer-boss] WARN  o.a.t.g.s.p.c.SparkGraphComputer - HADOOP_GREMLIN_LIBS is not set -- proceeding regardless

强调我很可能没有正确设置一些东西。

============================================== ======================
更新:10 月 27 日,星期二

通过将程序提交到具有一个从属节点的 Spark 集群,而不是通过 IDE 在本地运行它,我的时间从 6 分钟显着下降到 3 分钟。

【问题讨论】:

  • 需要多长时间?
  • @stephenmallette 大约需要 6 分钟

标签: java apache-spark gremlin janusgraph tinkerpop3


【解决方案1】:

即使对于小型数据集,基于 OLAP 的 Gremlin 遍历也会比标准 OLTP 遍历慢得多。仅让 Spark 准备好处理您的遍历就需要相当大的成本。仅此开销就很容易使您的 OLAP 查询比 OLTP 差 1 分钟。在您的问题的 cmets 中,您解释说您的查询大约需要六分钟。这似乎有点长,但可能在 OLAP 的正常范围内,具体取决于您的环境??

一些图表会针对 OLAP count() 进行优化,并为您提供非常快速的结果,但您将此问题标记为“JanusGraph”,所以我认为这不适用于此处。

在您开始关注大型图之前,您通常不会看到基于 OLAP 的遍历的价值。比较在 OLAP 和 OLTP 中计算 100+ 百万条边,您可能根本不会介意等待 6 分钟才能得到答案(因为 OLTP 可能根本无法完成)。

很难说你可以做些什么来加快你当前的设置,因为你实际上只是在证明事情在这一点上是有效的。现在您有了一个工作模型,我建议下一步是生成一个更大的图(可能有 1000 万个顶点),然后用一个合适大小的火花簇再次尝试计算。

【讨论】:

  • 老实说,我相信我在那里遇到了一些问题,由 43 个顶点和大约 60 条边组成的图 6 分钟太多了,我在项目运行期间唯一得到的东西来自我的 IDE 如下: 13:31:39.394 [JanusGraph Cluster-nio-worker-1] WARN c.d.driver.core.RequestHandler - Query '[4 bound values] SELECT column1,value,writetime(value) AS writetime,ttl( value) AS ttl FROM janusgraph.system_properties WHERE key=:key AND column1>=:sliceStart AND column1<:sliceend limit :maxrows>
  • 6 分钟确实看起来很长,但我只是想指出,如果您期望 OLAP 的响应时间为毫秒,因为图表很小,那么这是错误的假设。我看到你也有一篇关于 gremlin-users 的帖子,也许你还应该在那里发布更多关于你的环境的信息(所有东西都在一台机器上运行,如果是的话,那有多强大?如果不是一台机器,那么那个环境是什么?看起来像)。 HadoopMarc 在这些事情上很聪明——他可以提供帮助。供他人参考:groups.google.com/g/gremlin-users/c/GJ0OQ3csgHw/m/Bm-LE5kEBAAJ
  • 再次您好,非常感谢您的快速响应,我已经更新了问题,现在当我将作业提交到具有一个从属节点的 Spark 集群而不是通过我的 IDE 在本地运行时,总执行时间是 3 分钟而不是 6 分钟,这更正常吗?
  • 我认为我从未尝试过以这种方式测量 OLAP 性能,但我猜可能需要 1 到 3 分钟(尽管出于某种原因,我认为 3 分钟仍然较长) - 我会让 HadoopMarc 成为最终答案 - 他对 JanusGraph 所做的事情比我做的要多)。我想我要再次强调的一点是,在评估性能时,我通常会庆幸我用 OLAP 进行了 6 分钟的查询,因为我会将它与OLTP 将忙于完成宇宙的年龄:)
  • 好的,将在 gremlin-users 组中等待他的反馈。是的,我在一台 8 核和 24gb 内存的机器上运行它,所以它对于一些中等重型的东西应该足够了。我将尝试使用大量边和顶点填充数据库并重新执行作业,并查看执行时间。
猜你喜欢
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 2023-03-16
  • 1970-01-01
  • 2018-10-25
  • 2021-03-25
相关资源
最近更新 更多