java 中的并发 gremlin 服务器和图形查询
Concurrent gremlin-server and graph queries in java
我正在使用 TinkerPop3 编写 Java 应用程序。它与 Neo4j 图形通信,并使用 neo4j-gremlin 3.0.0.M7
库通过 Gremlin 发送 read/write 查询。
同时,我想使用 gremlin-server 3.0.0.M7
通过 HTTP 提供此图表。单独地,这些操作工作得很好。然而,由于不允许多个连接(即 GremlinServer
对象和 Java 代码都试图获得图上的锁),这似乎是不可能同时进行的。
当然,解决方法可能包括从 Java 程序中创建客户端并将其连接到服务器。但是,我宁愿消除这引入的通信开销。
大问题:这可能吗?
为了完整起见,这是我的最少代码。请注意,我的 gremlin-server-neo4j.yaml
指的是标准包含的 neo4j-empty.properties
文件,包含与我的 Java 代码(即 /tmp/neo4j
)中的 Neo4jGraph 对象相同的 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.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
如您所见,您尝试执行的操作不会起作用,因为两个单独的进程无法在嵌入式 Neo4jGraph
上运行。就目前而言,您无法从 GremlinServer
对象访问已配置的图形实例,我不确定我是否会更改它,因为我不完全确定这是一个有用的功能每个人。
在我看来,您需要的是 "initialize" 您的 Graph
实例的方法。如果是这样,那么 Gremlin Server 提供了一种方法来做到这一点。您可以在 yaml 文件中提供初始化脚本(以下是来自 conf/gremlin-server-classic.yaml
的片段,它与 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 Server 启动时托管,然后可以使用 [=18= 以标准方式简单地启动它].
我正在使用 TinkerPop3 编写 Java 应用程序。它与 Neo4j 图形通信,并使用 neo4j-gremlin 3.0.0.M7
库通过 Gremlin 发送 read/write 查询。
同时,我想使用 gremlin-server 3.0.0.M7
通过 HTTP 提供此图表。单独地,这些操作工作得很好。然而,由于不允许多个连接(即 GremlinServer
对象和 Java 代码都试图获得图上的锁),这似乎是不可能同时进行的。
当然,解决方法可能包括从 Java 程序中创建客户端并将其连接到服务器。但是,我宁愿消除这引入的通信开销。
大问题:这可能吗?
为了完整起见,这是我的最少代码。请注意,我的 gremlin-server-neo4j.yaml
指的是标准包含的 neo4j-empty.properties
文件,包含与我的 Java 代码(即 /tmp/neo4j
)中的 Neo4jGraph 对象相同的 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.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
如您所见,您尝试执行的操作不会起作用,因为两个单独的进程无法在嵌入式 Neo4jGraph
上运行。就目前而言,您无法从 GremlinServer
对象访问已配置的图形实例,我不确定我是否会更改它,因为我不完全确定这是一个有用的功能每个人。
在我看来,您需要的是 "initialize" 您的 Graph
实例的方法。如果是这样,那么 Gremlin Server 提供了一种方法来做到这一点。您可以在 yaml 文件中提供初始化脚本(以下是来自 conf/gremlin-server-classic.yaml
的片段,它与 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 Server 启动时托管,然后可以使用 [=18= 以标准方式简单地启动它].