JanusGraph 创建索引步骤(composite index)踩坑总结
前言
JanusGraph是一个图数据库引擎,安装及入门可以参考 JanusGraph 图数据库安装小记。为了提高查询速度,在使用过程中一般要为某些属性创建索引。这篇随笔主要是记录创建索引过程中踩过的坑。
索引介绍
与mysql创建索引不同,JanusGraph的索引有一套生命周期,如下图所示:

我们的目标是从<create>索引开始,通过一系列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]
到此,索引就创建完毕了,如果想要了解更多问题可以留言讨论,或者科学上网进一步学习。
JanusGraph 创建索引步骤(composite index)踩坑总结的更多相关文章
- ES建立索引步骤, 1,index 2.mapping 3,别名
1.建立索引PUT /index_trans_detail 2.建立mappingPOST /index_trans_detail/type_trans_detail/_mapping{ " ...
- SAS创建和使用索引(SAS INDEX)
一.概述 在合并数据集的时候,可以使用DATA步,但使用DATA 步时需要对KEY VALUE 排序,且KEY VALUE 的名字也必须一致:也可以用PROC SQL ,不需要进行上述排序.重命名的步 ...
- SQL语句-创建索引
语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100 GO USE 库名GO IF EXISTS (SELECT * FRO ...
- hive创建索引
索引是hive0.7之后才有的功能,创建索引需要评估其合理性,因为创建索引也是要磁盘空间,维护起来也是需要代价的 创建索引 hive> create index [index_studentid ...
- SQLServer 语句-创建索引
语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100GO /*实例*/USE 库名GOIF EXISTS (SELECT * ...
- 索引 使用use index优化sql查询
好博客:MySQL http://webnoties.blog.163.com/blog/#m=0&t=1&c=fks_08407108108708107008508508609508 ...
- 几百万的数据,mysql快速高效创建索引
有一个问题,一张表有3百万条记录,随着时间的增加,记录量会更多,此时查询速度很慢.在创建此表前没有未相应字段添加索引,所以此时需要为表添加索引.但是因为数据量大的原因,索引添加不成功,想了很多办法,终 ...
- SQLServer 语句-创建索引【转】
语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100GO /*实例*/USE 库名GOIF EXISTS (SELECT * ...
- hive:创建索引
hive也是支持索引的使用,但是如果表中已经有数据的情况下,创建索引的过程不是特别快. 已经拥有表: create table if not exists llcfpd_withgroupbykey( ...
随机推荐
- LeetCode 150. 逆波兰表达式求值(Evaluate Reverse Polish Notation) 24
150. 逆波兰表达式求值 150. Evaluate Reverse Polish Notation 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, /.每个运算对象 ...
- 03 Mybatis框架---学习笔记1--框架的概念及优势
1.框架的概念 框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统.简单说就是使用别人搭好的舞台,你来做表演.而且,框架一般是成熟的,不断升级的软件.框架是我们软件开发中的一套解决方 ...
- Java开发笔记(一百零七)URL地址的组成格式
URL的全称是Uniform Resource Locator,意思是统一资源定位符,俗称网络地址或网址.网络上的每个文件及接口,都有对应的URL网址,它规定了其他设备如何通过一系列的路径找到自己,犹 ...
- Altium Designer 复制报错-奇怪的问题解决办法
之前AD画原理图复制元件正常使用,今天使用时复制弹出了错误.很是诧异! 各种搜索查找问题,发现或许是因为前一段时间把,电脑上的所有打印机都删除了导致的. 就安装了一个打印机. 再复制,就不报错了. 或 ...
- go对elasticsearch的增删改查
环境 elasticsearch 6.8 (6.x版本应该都没问题) go客户端sdk: github.com/elastic/go-elasticsearch/v6 其实自己封装api也行,反正el ...
- Mysql中HAVING的相关使用方法
having字句可以让我们筛选分组之后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前. 而having子句在聚合后对组记录进行筛选.我的理解就是真实表 ...
- docker容器日志管理(清理)
原文:docker容器日志管理(清理) 前言 在使用docker容器时候,其日志的管理是我们不得不考虑的事情.因为docker容器的日志文件会占据大量的磁盘空间.下面介绍的就是对docker容器日志的 ...
- C# 使用代理实现方法过滤
一.为什么要进行方法过滤 一些情况下我们需要再方法调用前记录方法的调用时间和使用的参数,再调用后需要记录方法的结束时间和返回结果,当方法出现异常的时候,需要记录异常的堆栈和原因,这些都是与业务无关的代 ...
- 【POJ3613 Cow Relays】(广义矩阵乘法)
题目链接 先离散化,假设有\(P\)个点 定义矩阵\(A_{ij}\)表示\(i\)到\(j\)只经过一条边的最短路,\[{(A^{a+b})_{ij}=\min_{1\le k\le p} \{ ( ...
- vue中v-if和v-for指令最好不要同时使用
建议不要在与v-for相同的元素上使用v-if.因为v-for指令的优先级高于v-if当它们处于同一节点.v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for ...