【问题标题】:Concurrent gremlin-server and graph queries in javajava中的并发gremlin-server和图形查询
【发布时间】:2015-02-10 12:58:54
【问题描述】:

我正在用 TinkerPop3 编写一个 Java 应用程序。它与 Neo4j 图形通信,并使用 neo4j-gremlin 3.0.0.M7 库通过 Gremlin 发送读/写查询。

同时,我想通过 HTTP 使用 gremlin-server 3.0.0.M7 提供此图表。另外,这些操作工作得很好。但是,由于不允许多个连接,这似乎不可能同时进行(即GremlinServer 对象和 Java 代码都试图获得图形上的锁定)。

当然,解决方法可能涉及从 Java 程序中创建客户端并将其连接到服务器。但是,我宁愿消除这种引入的通信开销。

最大的问题:这可能吗?

为了完整起见,这是我的最小代码。请注意,我的gremlin-server-neo4j.yaml 指的是标准包含的neo4j-empty.properties 文件,它包含与我的Java 代码中的Neo4jGraph 对象相同的neo4j 图形数据目录(即/tmp/neo4j)。

import com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph;
import com.tinkerpop.gremlin.server.GremlinServer;
import com.tinkerpop.gremlin.server.Settings;    

public class Main {

    Neo4jGraph g;
    GremlinServer s;

    public static void main (String[] argv) {
        new Main().start();
    }

    private void start () {

        try {
            Settings settings = Settings.read(getClass().getResourceAsStream("/gremlin-server-neo4j.yaml"));
            s = new GremlinServer(settings);
            s.run();
        } catch (Exception e) {
            e.printStackTrace();
        }

        g = Neo4jGraph.open("/tmp/neo4j");

        // Gremlin code here

        g.close();
        s.stop();
    }
}

最后,例外:

Exception in thread "main" java.lang.RuntimeException: Error starting org.neo4j.kernel.EmbeddedGraphDatabase, /tmp/neo4j
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.<init>(Neo4jGraph.java:160)
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.open(Neo4jGraph.java:175)
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.open(Neo4jGraph.java:184)
    at org.test.Main.start(Main.java:33)
    at org.test.Main.main(Main.java:15)
Caused by: java.lang.RuntimeException: Error starting org.neo4j.kernel.EmbeddedGraphDatabase, /tmp/neo4j
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:366)
    at org.neo4j.kernel.EmbeddedGraphDatabase.<init>(EmbeddedGraphDatabase.java:59)
    at org.neo4j.graphdb.factory.GraphDatabaseFactory$1.newDatabase(GraphDatabaseFactory.java:91)
    at org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:181)
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.<init>(Neo4jGraph.java:133)
    ... 4 more
Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Component 'org.neo4j.kernel.StoreLockerLifecycleAdapter@67ec8477' was successfully initialized, but failed to start. Please see attached cause exception.
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:513)
    at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:115)
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:343)
    ... 8 more
Caused by: org.neo4j.kernel.StoreLockException: Unable to obtain lock on store lock file: /tmp/neo4j/store_lock. Please ensure no other process is using this database, and that the directory is writable (required even for read-only access)
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:82)
    at org.neo4j.kernel.StoreLockerLifecycleAdapter.start(StoreLockerLifecycleAdapter.java:44)
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:507)
    ... 10 more
Caused by: java.io.IOException: Unable to lock org.neo4j.kernel.impl.nioneo.store.StoreFileChannel@baf1bb3
    at org.neo4j.kernel.impl.nioneo.store.FileLock.wrapFileChannelLock(FileLock.java:38)
    at org.neo4j.kernel.impl.nioneo.store.FileLock.getOsSpecificFileLock(FileLock.java:93)
    at org.neo4j.kernel.DefaultFileSystemAbstraction.tryLock(DefaultFileSystemAbstraction.java:93)
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:74)
    ... 12 more

【问题讨论】:

    标签: java server gremlin tinkerpop3


    【解决方案1】:

    正如您所发现的,您尝试执行的操作将不起作用,因为两个单独的进程无法在嵌入式 Neo4jGraph 上运行。就目前而言,您无法从GremlinServer 对象访问已配置的图形实例,我不确定我是否会更改它,因为我不完全确定这是一个对每个人都有用的功能。

    在我看来,您需要的是一种“初始化”Graph 实例的方法。如果是这样,那么 Gremlin Server 提供了一种方法来做到这一点。您可以在 yaml 文件中提供初始化脚本(以下是来自 conf/gremlin-server-classic.yaml 的 sn-p,它与 Gremlin Server 分发包一起打包)。

    scriptEngines: {
      gremlin-groovy: {
        imports: [java.lang.Math],
        staticImports: [java.lang.Math.PI],
        scripts: [scripts/generate-classic.groovy]}}
    

    注意“scripts”键,它可以让你提供脚本文件来执行。这些脚本将使您能够访问“g”(或您配置的任何图表)。对于此示例,scripts/generate-classic.groovy 仅具有:

    TinkerFactory.generateClassic(g)
    

    通过这种方式,您可以在 Graph 上完成所有初始化工作,Gremlin 服务器在启动时最终将托管它,然后可以使用 bin/gremlin-server.sh 以标准方式简单地启动它。

    【讨论】:

    • 感谢您的快速回复!这是否意味着在指定的脚本完成运行之前服务器不会开始服务?在我的特定应用程序中,我想执行一个与服务器同时运行的脚本,但据我了解,这样的脚本只是一个初始化步骤(保持锁定直到完成,允许服务器抓取之后锁定)。让这样的脚本永远运行会导致服务器永远不会启动吗?
    • 初始化脚本将阻塞,直到它完成执行。所以服务器在完成之前不会开始服务。如果您想让该脚本在服务器的整个生命周期内持续运行(并避免阻塞),我想您必须在脚本中启动一个单独的线程。问题在于如何很好地停止该线程,因为不会有触发器知道服务器何时关闭。我不反对对 Gremlin Server 进行更改以提供该挂钩作为可从脚本访问的绑定。看到这个问题:github.com/tinkerpop/tinkerpop3/issues/553
    • 好的,那我现在就使用客户端方法。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 2016-09-23
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多