JanusGraph 创建索引步骤(composite index)踩坑总结

Wesley13
• 阅读 633

前言

JanusGraph是一个图数据库引擎,安装及入门可以参考 JanusGraph 图数据库安装小记。为了提高查询速度,在使用过程中一般要为某些属性创建索引。这篇随笔主要是记录创建索引过程中踩过的坑。

索引介绍

与mysql创建索引不同,JanusGraph的索引有一套生命周期,如下图所示:

JanusGraph 创建索引步骤(composite index)踩坑总结

我们的目标是从索引开始,通过一系列action,最终使索引进入ENABLED状态。

下面简单说明以下各个状态及操作:

States(SchemaStatus)

  • INSTALLED The index is installed in the system but not yet registered with all instances in the cluster
  • REGISTERED The index is registered with all instances in the cluster but not (yet) enabled
  • ENABLED The index is enabled and in use (到这一步索引就可以用啦)
  • DISABLED    The index is disabled and no longer in use (删除索引)

Actions (SchemaAction)

  • REGISTER_INDEX Registers the index with all instances in the graph cluster. After an index is installed, it must be registered with all graph instances
  • REINDEX Re-builds the index from the graph(如果我们创建索引时已经存在数据,需要执行这个Action)
  • ENABLE_INDEX Enables the index so that it can be used by the query processing engine. An index must be registered before it can be enabled
  • **DISABLE_INDEX     ** Disables the index in the graph so that it is no longer used
  • REMOVE_INDEX Removes the index from the graph (optional operation). Only on composite index

创建索引

创建索引的JanusGraph官方教程所描述的方法是一种理想情况,命令如下:

graph.tx().rollback()

mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
mgmt.buildIndex('byNameComposite', Vertex.class).addKey(name).buildCompositeIndex()

//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameComposite').call()

//Reindex the existing data
mgmt.updateIndex(mgmt.getGraphIndex("byNameComposite"), SchemaAction.REINDEX).get()

mgmt.commit()

实际上在操作时会遇到很多问题,其中最头疼的就是在执行 awaitGraphIndexStatus()方法时,会报 “Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 30000 ms or evaluation was otherwise cancelled directly for request [mgmt.awaitGraphIndexStatus(graph, 'byNameComposite').call()]” 的错误。

上面的命令其实忽略了关键的几步,下面具体说明以下。

1. 创建索引之前,确定JanusGraph没有其它事务正在运行

官方文档说明如下:

The name of a graph index must be unique. Graph indexes built against newly defined property keys, i.e. property keys that are defined in the same management transaction as the index, are immediately available. Graph indexes built against property keys that are already in use require the execution of a reindex procedure to ensure that the index contains all previously added elements. Until the reindex procedure has completed, the index will not be available. It is encouraged to define graph indexes in the same transaction as the initial schema.

查询事务命令:

graph.getOpenTransactions()

假设有其它3条事务,通过官方的 graph.tx().rollback() 命令是无法全部关闭的,实际情况如下

gremlin> graph.getOpenTransactions()
==>standardtitantx[0x1e14c346]
==>standardtitantx[0x7a0067f2]
==>standardtitantx[0x0de3ee40]
gremlin> graph.tx().rollback()
==>null
gremlin> graph.getOpenTransactions()
==>standardtitantx[0x1e14c346]
==>standardtitantx[0x7a0067f2]
==>standardtitantx[0x0de3ee40]

正确的关闭方法:

for(i=0;i<size;i++) {graph.getOpenTransactions().getAt(0).rollback()}  //size替换为事务的数量

2. 执行 REGISTER_INDEX ACTION,使索引状态INSTALLED 转为 REGISTERED

官方文档里没有这关键的一步,在创建完索引后,需要执行以下命令

m = graph.openManagement()
m.updateIndex(m.getGraphIndex('index'), SchemaAction.REGISTER_INDEX).get()
m.commit()

其中第三条命令执行后实际上是在后台运行的,此时如果我们执行  ManagementSystem.awaitGraphIndexStatus(graph,"byNameComposite").status(SchemaStatus.REGISTERED).call() ,等待30s后很可能依然返回超时错误。这时候需要耐心等待。期间,我们可以通过查看后台cassandra进程CPU占用率来判断是否执行完成。或者可以直接查看索引的状态:

mgmt = graph.openManagement()index = mgmt.getGraphIndex('index')
Index.getIndexStatus(mgmt.getPropertyKey('name'))

  等待一段时间后,索引的状态最终会变为 REGISTERED,此时再执行awaitGraphIndexStatus() ,会返回

GraphIndexStatusReport[success=true, indexName='byTitleLowercaseComposite', targetStatus=[REGISTERED], notConverged={}, converged={title_lowercase=REGISTERED}, elapsed=PT0.001S]

   注意:若索引迟迟没有变为REGISTERED,也可尝试进行下一步,更新到ENABLE。

  3. 执行REINDEX与ENABLE_INDEX,完成索引

与上一步类似,需要通过updateIndex()方法来改变索引状态。如果要索引的属性中还未导入数据,则不需要REINDEX的操作,下面的命令二选一:

REINDEX ACTION:

m = graph.openManagement()
m.updateIndex(m.getGraphIndex('index'), SchemaAction.REINDEX).get()
m.commit()

ManagementSystem.awaitGraphIndexStatus(graph, 'byNameComposite').status(SchemaStatus.ENABLED).call()

   ENABLED ACTION:

m = graph.openManagement()
m.updateIndex(m.getGraphIndex('index'), SchemaAction.ENABLE_INDEX).get() m.commit() ManagementSystem.awaitGraphIndexStatus(graph, 'byNameComposite').status(SchemaStatus.ENABLED).call()错误示例: i = m.getGraphIndex('index')m.updateIndex(i, SchemeAction.ENABLE_INDEX)m.commit()必须要加‘get()’

  到最后, 执行awaitGraphIndexStatus()返回成功信息:

GraphIndexStatusReport[success=true, indexName='byTitleLowercaseComposite', targetStatus=[ENABLED], notConverged={}, converged={title_lowercase=ENABLED}, elapsed=PT0.001S]

到此,索引就创建完毕了,如果想要了解更多问题可以留言讨论,或者科学上网进一步学习。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
2年前
P2P技术揭秘.P2P网络技术原理与典型系统开发
Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这