server能被配置ConfiguredGraphFactory。ConfiguredGraphFactory是一个图的访问点,类似于JanusGraphFactory。这些factories提供方法动态管理图。
9.1 总览
JanusGraphFactory是一个提供访问点到你的图的class,通过你每次访问图提供一个配置object。
ConfiguredGraphFactory提供是一个提供访问点到你的图,用于你之前ConfigurationManagementGraph创建的配置。它也提供访问点给管理图配置。
ConfigurationManagementGraph允许你管理图配置。
JanusGraphManager是一个内部的服务器组件,用来追踪图相关,前提是您的图形被配置为使用它。
9.2 JanusGraphManager与JanusGraphFactory
这里,两个工厂类有重要的区分如下:
- 如果你在server启动时配置了使用ConfigurationManagementGraphAPIS,才能用ConfiguredGraphFactory。
使用ConfiguredGraphFactory好处如下:
- 你只需要提供一个String来访问你的图,而JanusGraphFactory在每次打开一个图、访问图时需要你指定后端信息。
- 如果你的ConfigurationManagementGraph配置了一个分布式的后端,你的图配置在cluster中所有janusgraph节点可用。
9.3 ConfiguredGraphFactory如何工作
在下面两种场景里,ConfiguredGraphFactory提供访问点:
- 你已经用ConfigurationManagementGraph#createConfiguration给你的图对象创建了配置文件。在这种场景,你的图是打开的,基于前面创建的配置。
- 你已经用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 更新配置
所有JanusGraphFactory和JanusGraphFactory的交互配置需要定义准确的graph.graphname,通过JanusGraphManager保持追踪给定JVM里相关的图,可以认为是图缓存。
重要提示
集群中每个节点的图缓存,任何的更新对相关的图影响是相互的,前提是每个节点正确配置JanusGraphManager。consistency
因此用模板创建图是有重复的问题的,这意味着:
重要提示
用模板创建的图的任何更新并不保证生效,直到满足:
- 相关配置被移除:ConfiguredGraphFactory.removeConfiguration("graph2")
- 用模板重新创建:ConfiguredGraphFactory.create("graph2")
9.8.4 更新例子
- 变更使用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");
- 增加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");
- 更新用模板创建的配置
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提供:
- 一个协作机制,哪个节点实例化相关图
- 相关图追踪器(或缓存)
任何用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.properties和conf/graph2.properties将不包括准确的graph.graphname,图将存在JanusGraphManager,在gremlin脚本执行时分别对应graph1和graph2。
9.9.2 重要的
为了方便,如果你的配置文件用来打开一个指定graph.graphname的图,但没有规定后端存储目录,表名和域名空间,那这些相关参数会自动设置给graph.graphname。然后如果你提供了参数,将会优先使用。如果都没有提供,会使用默认值。
storage.root是一个特殊例子,这个是新配置用来指定根目录,用来给后端存储需要的本地访问存储目录。如果你提供了这个参数,那么也必须提供准确的graph.graphname,存储的绝对路径将等于graph.graphname的参数附加到storage.root参数后面。
下面是使用例子:
- 给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
- 给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的执行器上下文,而图的遍历绑定到上下文
从这里了解更多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