JanusGraph索引的基本操作及性能测试

JanusGraph索引的探索

1. 索引的操作

JansuGraph中索引生命周期:基本上所有的关于索引的操作都属于这张图中的操作

JanusGraph索引的基本操作及性能测试_第1张图片

1.1 操作前的准备

在对索引进行操作之前,需要确保没有正在进行的事务,并且确保没有影子实例

使用命令graph.getOpenTransactions()去查看当前是否有正在进行中的事务

gremlin> graph.getOpenTransactions()
==>standardjanusgraphtx[0x32507479]

如果有正在进行的事务,我们需要把这些事务提交或者回滚。一般的回滚操作:

graph.tx().rollback()

如果使用此命令后仍有其他事务正在进行,可以使用这个命令回滚多个事务:

for(i=0;i

最后确认没有正在进行的事务再进行下一步操作

1.2 索引生命周期

1.2.1 创建

创建复合索引

//开始事务
mgmt = graph.openManagement()
//获取属性键
idPropertyKey = mgmt.getPropertyKey('id') 
//创建复合索引
mgmt.buildIndex('byIdComposite',Vertex.class).addKey(idPropertyKey).buildCompositeIndex()
//提交事务
mgmt.commit()

创建混合索引

//开始事务
mgmt = graph.openManagement()
//获取属性键
idPropertyKey = mgmt.getPropertyKey('id') 
//创建混合索引'search'是索引后端名称,与配置文件中配置的名称对应index.search.backend=elasticsearch
mgmt.buildIndex('byIdComposite',Vertex.class).addKey(idPropertyKey).buildMixedIndex('search')
//提交事务
mgmt.commit()

创建中心顶点索引

//开始事务
mgmt = graph.openManagement()
//获取属性键
idPropertyKey = mgmt.getPropertyKey('id') 
//获取边标签
tag = mgmt.getEdgeLabel('tosca.relationships.network.Tag')
//创建中心顶点索引
mgmt.buildEdgeIndex(tag, 'edgeId', Direction.BOTH, Order.desc, idPropertyKey)
//提交事务
mgmt.commit()

JanusGraph索引的基本操作及性能测试_第2张图片

提交事务后,可以使用printSchema()查看索引是否已添加到Schema。如图,索引已经创建并且为INSTALLED状态(在理想状态下,索引会自动的更新为REGISTERED状态)

1.2.2 注册

对于索引上已原有数据的情况,接下来,我们需要将索引的状态从INSTALLED更新到REGISTERED状态

//打开事务
mgmt = graph.openManagement()
//更新图形索引状态
mgmt.updateIndex(mgmt.getGraphIndex('byIdComposite'), SchemaAction.REGISTER_INDEX).get()
//更新中心节点索引状态
tag = mgmt.getEdgeLabel('tosca.relationships.network.Tag')
mgmt.updateIndex(mgmt.getRelationIndex(tag, 'edgeId'), SchemaAction.REGISTER_INDEX).get()
//提交事务
mgmt.commit()
//等待索引更新状态(这一步可能会耗费比较久的时间,要耐心等待。若迟迟没有更新,也可以尝试进行下一步操作)
ManagementSystem.awaitGraphIndexStatus(graph,"byIdComposite").status(SchemaStatus.REGISTERED).call()

查看索引状态

mgmt = graph.openManagement()
index = mgmt.getGraphIndex('byIdComposite')
index.getIndexStatus(mgmt.getPropertyKey('id'))

//或者
ManagementSystem.awaitGraphIndexStatus(graph,"byIdComposite").status(SchemaStatus.REGISTERED).call()

//或者
mgmt.printSchema()

JanusGraph索引的基本操作及性能测试_第3张图片

1.2.3 可用

接下来,将索引从REGISTERED更新为ENABLE状态

如果该索引字段已经存有数据,则需要重做索引,如果是新的字段,则直接应用,这两种操作都能使索引更新为ENABLE状态

//重做索引
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byIdComposite"), SchemaAction.REINDEX).get()
mgmt.commit()

//应用索引
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byIdComposite"), SchemaAction.ENABLE_INDEX).get()
mgmt.commit()

//中心顶点索引
ManagementSystem.awaitRelationIndexStatus(graph, 'edgeId').call()
mgmt = graph.openManagement()
tag = mgmt.getEdgeLabel('tosca.relationships.network.Tag')
mgmt.updateIndex(mgmt.getRelationIndex(tag, "edgeId"), SchemaAction.REINDEX).get()
mgmt.commit()

至此,此索引已经可以在查询中被使用(在查询中不再被提示WARN: Query requires iterating over all vertices. For better performance, use indexes)

JanusGraph索引的基本操作及性能测试_第4张图片

1.2.4 冻结

对已有的索引,冻结操作可以使索引不再有效。值得注意的是,冻结的步骤是不可反向的,即冻结状态无法再还原为创建/注册/可用。

mgmt = graph.openManagement()
//复合索引
mgmt.updateIndex(mgmt.getGraphIndex('byIdComposite'), SchemaAction.DISABLE_INDEX).get()
//混合索引
mgmt.updateIndex(mgmt.getGraphIndex('nameMixed'), SchemaAction.DISABLE_INDEX).get()
//中心顶点索引
mgmt.updateIndex(mgmt.getRelationIndex(tag, 'edgeId'), SchemaAction.DISABLE_INDEX).get()

mgmt.commit()

1.2.5 移除

移除和冻结一样,也是不可逆的操作。值得注意的是,对于不同类型的索引要求的移除操作不同。

复合索引和中心顶点索引只需通过JanusGraph进行移除操作即可,但混合索引需要使用索引后端进行移除。

删除索引操作删除了与索引相关联的所有内容,除了其模式定义和DISABLED状态。 该索引的架构存根即使在删除后仍然保留,尽管其存储占用空间可以忽略不计并且是固定的。 个人实践:JanusGraph禁用索引置为DISABLED状态,但在通过JanusGraph查询这个索引索引仍然会存在。即使通过ElasticSearch删除了索引数据,但JanusGraph中这个索引仍然是可以查到的,但状态是DISABLED。为什么删除索引还要保存这个架构?有待JanusGraph官方解答。

JanusGraph索引的基本操作及性能测试_第5张图片

1.3 索引对性能的提升

1.3.1 在查询任意节点时的性能对比

查询任意一个指定id的节点,使用id的复合节点

g.V().has('id','d47395f69354440f918acf2166abba48')
查询记录 无索引 id复合索引
第一次查询(无查询缓存) 8s <1s
第二次查询(有查询缓存) 3s <1s
第三次查询(有查询缓存) 2s <1s

1.3.2 在查询客户产品物理链路时的性能对比

在相同条件下查询同一个客户产品物理链路

查询记录 无索引 id复合索引+中心顶点索引
第一次查询(无查询缓存) 60s 28s
第二次查询(有查询缓存) 42s 18s
第三次查询(有查询缓存) 41s 18s

附录1 图库常用的Gremlin命令

  • 打开图数据
 graph = JanusGraphFactory.open('conf/janusgraph-berkeleyje-es.properties')
  • 获取遍历句柄
g = graph.traversal()
  • 开启事务
mgmt = graph.openManagement()
  • 查看进行中事务
graph.getOpenTransactions()
  • 回滚事务
//回滚当前正在进行的事务
graph.tx().rollback()

//回滚多条事务
for(i=0;i
  • 打印Schema结构
mgmt = graph.openManagement()

//打印Schema
mgmt.printSchema()
//打印边标签
mgmt.printEdgeLabels()
//打印顶点标签
mgmt.printVertexLabels()
//打印属性键
mgmt.printPropertyKeys()
//打印索引
mgmt.printIndexes()

你可能感兴趣的:(nosql)