Chapter 9. ConfiguredGraphFactory

server能被配置ConfiguredGraphFactoryConfiguredGraphFactory是一个图的访问点,类似于JanusGraphFactory。这些factories提供方法动态管理图。

9.1 总览

JanusGraphFactory是一个提供访问点到你的图的class,通过你每次访问图提供一个配置object。

ConfiguredGraphFactory提供是一个提供访问点到你的图,用于你之前ConfigurationManagementGraph创建的配置。它也提供访问点给管理图配置。

ConfigurationManagementGraph允许你管理图配置。

JanusGraphManager是一个内部的服务器组件,用来追踪图相关,前提是您的图形被配置为使用它。

9.2 JanusGraphManager与JanusGraphFactory

这里,两个工厂类有重要的区分如下:

  1. 如果你在server启动时配置了使用ConfigurationManagementGraphAPIS,才能用ConfiguredGraphFactory

使用ConfiguredGraphFactory好处如下:

  1. 你只需要提供一个String来访问你的图,而JanusGraphFactory在每次打开一个图、访问图时需要你指定后端信息。
  2. 如果你的ConfigurationManagementGraph配置了一个分布式的后端,你的图配置在cluster中所有janusgraph节点可用。

9.3 ConfiguredGraphFactory如何工作

在下面两种场景里,ConfiguredGraphFactory提供访问点:

  1. 你已经用ConfigurationManagementGraph#createConfiguration给你的图对象创建了配置文件。在这种场景,你的图是打开的,基于前面创建的配置。
  2. 你已经用ConfigurationManagementGraph#createTemplateConfiguration创建了模板配置。在这种场景,我们创建一个配置文件给你创建的图,通过拷贝模板配置中所有的参数,并且附加相关的图名称属性,然后会根据这个配置打开图。

9.4 访问图

你可以用ConfiguredGraphFactory.create("graphName")或者ConfiguredGraphFactory.open("graphName")。两种的区别可以参考下面的ConfigurationManagementGraph

你可以可以访问图通过binding,可以参考Graph and Traversal Bindings

9.5 列表展示图

ConfiguredGraphFactory.getGraphNames()将返回图名称的集合,这些图根据你用ConfigurationManagementGraphAPIs创建的。

JanusGraphFactory.getGraphNames()返回图名称的集合,那些你用JanusGraphManager实例化的,和参考引入的。

9.6 丢弃图

ConfiguredGraphFactory.drop("graphName")会丢弃图,删除所有存储和索引后端数据,图可以是打开或者关闭状态(drop会先close)。而且,还将移除ConfigurationManagementGraph里的所有图配置。

重要提示

这将是不可恢复的,将删除所有图和索引的数据。

重要提示

确保所有图表达持续可用于集群中所有节点,这个操作会从集群中所有节点的JanusGraphManager缓存中移除,前提是所有节点的JanusGraphManager配置正确。consistency来了解更多。

9.7为ConfiguredGraphFactory配置你的server

为能用ConfiguredGraphFactory,你必须用ConfigurationManagementGraphAPIs配置你的server,你必须插入名为ConfigurationManagementGraph的图变量到你的server yaml文件,例如:

graphManager: org.janusgraph.graphdb.management.JanusGraphManager
graphs: {
  ConfigurationManagementGraph: conf/JanusGraph-configurationmanagement.properties
}

这个例子里,我们的ConfigurationManagementGraph图用conf/JanusGraph-configurationmanagement.properties作为配置文件,内容如下:

gremlin.graph=org.janusgraph.core.JanusGraphFactory
storage.backend=cql
graph.graphname=ConfigurationManagementGraph
storage.hostname=127.0.0.1

假设server启动成功,ConfigurationManagementGraph完成实例化,所有ConfigurationManagementGraph Singleton里的APIs都可用,将实现上面的图。这个图将使用ConfiguredGraphFactory来create/open图。

重要提示

JanusGraph发行版中包含的pom.xml将此依赖项列为可选项,但ConfiguredGraphFactory使用了JanusGraphManager,它需要声明对org.apache.tinkerpop:gremlin-server的依赖。因此,如果您遇到NoClassDefFoundError错误,那么请确保根据此消息进行更新。

9.8 ConfigurationManagementGraph

ConfigurationManagementGraph是一个单例,允许你create/update/remove配置,用ConfiguredGraphFactory访问图的配置,看上面的内容确保你能使用APIs。

重要提示

ConfiguredGraphFactory提供一个访问点,去管理你的ConfigurationManagementGraph管理的配置,所以并不是直接操作你的单例,而是通过ConfiguredGraphFactory静态方法操作。例如你可以用ConfiguredGraphFactory.removeTemplateConfiguration(),而不是ConfiguredGraphFactory.getInstance().removeTemplateConfiguration()

9.8.1 图配置

ConfigurationManagementGraph单例允许你创建配置打开指定的图,根据graph.graphname property,例如:

map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
map.put("graph.graphname", "graph1");
ConfiguredGraphFactory.createConfiguration(new MapConfiguration(map));

然后你可以在任意节点访问图:

ConfiguredGraphFactory.open("graph1");
9.8.2 配置模板

ConfigurationManagementGraph也允许你创建一个配置模板,你可以用同一个模板创建许多图,例如:

map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));

这之后,你可以用模板创建图:

ConfiguredGraphFactory.create("graph2");

这个方法将创建一个graph2的新配置,通过拷贝模板配置中所有相关参数,和为这个图存储一个配置。这样这个图就可以被访问,下一步可以操作:

ConfiguredGraphFactory.open("graph2");
9.8.3 更新配置

所有JanusGraphFactoryJanusGraphFactory的交互配置需要定义准确的graph.graphname,通过JanusGraphManager保持追踪给定JVM里相关的图,可以认为是图缓存。

重要提示

集群中每个节点的图缓存,任何的更新对相关的图影响是相互的,前提是每个节点正确配置JanusGraphManager。consistency

因此用模板创建图是有重复的问题的,这意味着:

重要提示

用模板创建的图的任何更新并不保证生效,直到满足:

  1. 相关配置被移除:ConfiguredGraphFactory.removeConfiguration("graph2")
  2. 用模板重新创建:ConfiguredGraphFactory.create("graph2")
9.8.4 更新例子
  1. 变更使用Cassandra数据到新的ip server
map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
map.put("graph.graphname", "graph1");
ConfiguredGraphFactory.createConfiguration(new
MapConfiguration(map));

g1 = ConfiguredGraphFactory.open("graph1");

// Update configuration
map = new HashMap();
map.put("storage.hostname", "10.0.0.1");
ConfiguredGraphFactory.updateConfiguration("graph1",
map);

// We are now guaranteed to use the updated configuration
g1 = ConfiguredGraphFactory.open("graph1");
  1. 增加es节点到配置里
map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
map.put("graph.graphname", "graph1");
ConfiguredGraphFactory.createConfiguration(new
MapConfiguration(map));

g1 = ConfiguredGraphFactory.open("graph1");

// Update configuration
map = new HashMap();
map.put("index.search.backend", "elasticsearch");
map.put("index.search.hostname", "127.0.0.1");
map.put("index.search.elasticsearch.transport-scheme", "http");
ConfiguredGraphFactory.updateConfiguration("graph1",
map);

// We are now guaranteed to use the updated configuration
g1 = ConfiguredGraphFactory.open("graph1");
  1. 更新用模板创建的配置
map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
ConfiguredGraphFactory.createTemplateConfiguration(new
MapConfiguration(map));

g1 = ConfiguredGraphFactory.create("graph1");

// Update template configuration
map = new HashMap();
map.put("index.search.backend", "elasticsearch");
map.put("index.search.hostname", "127.0.0.1");
map.put("index.search.elasticsearch.transport-scheme", "http");
ConfiguredGraphFactory.updateTemplateConfiguration(new
MapConfiguration(map));

// Remove Configuration
ConfiguredGraphFactory.removeConfiguration("graph1");

// Recreate
ConfiguredGraphFactory.create("graph1");
// Now this graph's configuration is guaranteed to be updated

9.9 JanusGraphManager

JanusGraphManager是一个单例,依附于TinkerPop graphManager的规范。

特定的,JanusGraphManager提供:

  1. 一个协作机制,哪个节点实例化相关图
  2. 相关图追踪器(或缓存)

任何用graph.graphname属性创建的图,将通过JanusGraphManager确定协作来实例化,相关图也会放到这个JVM的图缓存中。

因而,你用graph.graphname属性打开的任意图,已经在指定JVM中实例化,并将从缓存中可以复用。

这也是为什么更新配置时需要一些步骤保证生效。

9.9.1 如何使用JanusGraphManager

当在配置文件中定义参数如何访问图,有一些配置选项可以使用。所有配置将在JanusGraphManager进行图实例化发生时生效。

后置兼容性考虑,任何图只支持配置在yaml文件中的图对象,在server启动时加载,那些图将通过JanusGraphManager加载他们的key和对象配置,如:

graphManager: org.janusgraph.graphdb.management.JanusGraphManager
graphs {
  graph1: conf/graph1.properties,
  graph2: conf/graph2.properties
}

conf/graph1.propertiesconf/graph2.properties将不包括准确的graph.graphname,图将存在JanusGraphManager,在gremlin脚本执行时分别对应graph1graph2

9.9.2 重要的

为了方便,如果你的配置文件用来打开一个指定graph.graphname的图,但没有规定后端存储目录,表名和域名空间,那这些相关参数会自动设置给graph.graphname。然后如果你提供了参数,将会优先使用。如果都没有提供,会使用默认值。
storage.root是一个特殊例子,这个是新配置用来指定根目录,用来给后端存储需要的本地访问存储目录。如果你提供了这个参数,那么也必须提供准确的graph.graphname,存储的绝对路径将等于graph.graphname的参数附加到storage.root参数后面。

下面是使用例子:

  1. 给Cassandra创建模板配置,每个创建的图获得一个独立的域名空间,等于提供给factory的String
map = new HashMap();
map.put("storage.backend", "cql");
map.put("storage.hostname", "127.0.0.1");
ConfiguredGraphFactory.createTemplateConfiguration(new
MapConfiguration(map));

g1 = ConfiguredGraphFactory.create("graph1"); //keyspace === graph1
g2 = ConfiguredGraphFactory.create("graph2"); //keyspace === graph2
g3 = ConfiguredGraphFactory.create("graph3"); //keyspace === graph3
  1. 给BerkeleyJE创建模板配置,每个图的存储目录等于/
map = new HashMap();
map.put("storage.backend", "berkeleyje");
map.put("storage.root", "/data/graphs");
ConfiguredGraphFactory.createTemplateConfiguration(new
MapConfiguration(map));

g1 = ConfiguredGraphFactory.create("graph1"); //storage directory === /data/graphs/graph1
g2 = ConfiguredGraphFactory.create("graph2"); //storage directory === /data/graphs/graph2
g3 = ConfiguredGraphFactory.create("graph3"); //storage directory === /data/graphs/graph3

9.10 图和遍历binding

使用ConfiguredGraphFactory创建的图,用graph.graphname绑定到server的执行器上下文,而图的遍历绑定到上下文_traversal。这意味着,在第一次create/open图之后,随后连接到server你可以访问或者遍历图用_traversal。

从这里了解更多bingding

重要提示

如果你用console和session的连接到一个远端server,你将必须重连server来bind变量,这也适用于所有session的连接。

重要提示

JanusGraphManagerrebindConfigurationManagementGraph里的每个图每20秒,这意味着使用ConfigredGraphFactory创建的你的图和遍历binding将在所有节点最多有20秒的延迟后可用。也意味着server重启后在节点binding仍然可用。

9.10.1 binding例子
gremlin> :remote connect tinkerpop.server conf/remote.yaml
==>Configured localhost/127.0.0.1:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182] - type ':remote console' to return to local mode
gremlin> ConfiguredGraphFactory.open("graph1")
==>standardjanusgraph[cassandrathrift:[127.0.0.1]]
gremlin> graph1
==>standardjanusgraph[cassandrathrift:[127.0.0.1]]
gremlin> graph1_traversal
==>graphtraversalsource[standardjanusgraph[cassandrathrift:[127.0.0.1]], standard]

9.11 例子

当创建一个Configured Graph Factory模板时建议使用session的连接,如果模板没有用session连接,创建必须用;分隔的一行里。

gremlin> :remote connect tinkerpop.server conf/remote.yaml session
==>Configured localhost/127.0.0.1:8182

gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost:8182]-[5206cdde-b231-41fa-9e6c-69feac0fe2b2] - type ':remote console' to return to local mode

gremlin> ConfiguredGraphFactory.open("graph");
Please create configuration for this graph using the
ConfigurationManagementGraph API.

gremlin> ConfiguredGraphFactory.create("graph");
Please create a template Configuration using the
ConfigurationManagementGraph API.

gremlin> map = new HashMap();
gremlin> map.put("storage.backend", "cql");
gremlin> map.put("storage.hostname", "127.0.0.1");
gremlin> map.put("GraphName", "graph1");
gremlin> ConfiguredGraphFactory.createConfiguration(new MapConfiguration(map));
Please include in your configuration the property "graph.graphname".

gremlin> map = new HashMap();
gremlin> map.put("storage.backend", "cql");
gremlin> map.put("storage.hostname", "127.0.0.1");
gremlin> map.put("graph.graphname", "graph1");
gremlin> ConfiguredGraphFactory.createConfiguration(new MapConfiguration(map));
==>null

gremlin> ConfiguredGraphFactory.open("graph1").vertices();

gremlin> map = new HashMap(); map.put("storage.backend",
"cql"); map.put("storage.hostname", "127.0.0.1");
gremlin> map.put("graph.graphname", "graph1");
gremlin> ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));
Your template configuration may not contain the property
"graph.graphname".

gremlin> map = new HashMap();
gremlin> map.put("storage.backend",
"cql"); map.put("storage.hostname", "127.0.0.1");
gremlin> ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));
==>null

// Each graph is now acting in unique keyspaces equivalent to the
graphnames.
gremlin> g1 = ConfiguredGraphFactory.open("graph1");
gremlin> g2 = ConfiguredGraphFactory.create("graph2");
gremlin> g3 = ConfiguredGraphFactory.create("graph3");
gremlin> g2.addVertex();
gremlin> l = [];
gremlin> l << g1.vertices().size();
==>0
gremlin> l << g2.vertices().size();
==>1
gremlin> l << g3.vertices().size();
==>0

// After a graph is created, you must access it using .open()
gremlin> g2 = ConfiguredGraphFactory.create("graph2"); g2.vertices().size();
Configuration for graph "graph2" already exists.

gremlin> g2 = ConfiguredGraphFactory.open("graph2"); g2.vertices().size();
==>1

你可能感兴趣的:(Chapter 9. ConfiguredGraphFactory)