Amazon dynamodb 无法创建复合索引,卡在已安装的位置

Amazon dynamodb 无法创建复合索引,卡在已安装的位置,amazon-dynamodb,titan,gremlin,Amazon Dynamodb,Titan,Gremlin,我无法创建索引。我的小精灵代码如下: usernameProperty = mgmt.getPropertyKey('username') usernameIndex = mgmt.buildIndex('byUsernameUnique', Vertex.class).addKey(usernameProperty).unique().buildCompositeIndex() mgmt.setConsistency(usernameIndex, ConsistencyModifier.LOC

我无法创建索引。我的小精灵代码如下:

usernameProperty = mgmt.getPropertyKey('username')
usernameIndex = mgmt.buildIndex('byUsernameUnique', Vertex.class).addKey(usernameProperty).unique().buildCompositeIndex()
mgmt.setConsistency(usernameIndex, ConsistencyModifier.LOCK)
mgmt.commit()
在我收到两个错误后不久:

18:04:57错误com.thinkaurelius.titan.graphdb.database.management.ManagementLogger-已收回[1@0a00009d2537-ip-10-0-0-1572]来自缓存,但等待事务关闭的时间太长。[standardtitantx[0x6549ce71]上的过时事务警报 18:04:57错误com.thinkaurelius.titan.graphdb.database.management.ManagementLogger-已收回[1@0a00009d2537-ip-10-0-0-1572]来自缓存,但等待事务关闭的时间太长。[standardtitantx[0x2a2815cc],standardtitantx[0x025dc2c0]上的过时事务警报

索引的状态卡在已安装的
位置

usernameIndex.getIndexStatus(usernameProperty)
==>INSTALLED
我了解到一个失败的实例可能会导致问题,但对正在运行的实例的检查只显示了一个:

mgmt.getOpenInstances()
==>0a00009d3011-ip-10-0-0-1572(current)
我还尝试发出一个
REGISTER\u INDEX
操作,该操作也会从事务缓存中退出,并显示类似的错误消息:

mgmt.updateIndex(usernameIndex, SchemaAction.REGISTER_INDEX).get()
mgmt.commit()
我还多次尝试重新启动服务器

注册过程似乎只是超时,导致从事务缓存中“逐出”。我等了48个小时只是为了确定这不是一个缓慢的过程。正常的读取、写入和对Titan的相关提交似乎工作正常,我只是无法创建此索引。我卡住了,还有什么我可以试试的吗?有没有办法延长该事务的超时时间

我正在使用DynamoDB后端运行Titan 1.0.0(使用提供的AWS进行设置)

编辑: 下面是我粘贴到Gremlin中的完整命令,添加了@m-T-A建议的
waitgraphstatus
步骤:

mgmt = graph.openManagement();
usernameIndex = mgmt.getPropertyKey('usernameIndex');
mgmt.buildIndex('byUsername',Vertex.class).addKey(usernameIndex).unique().buildCompositeIndex();
// I have tried with and without a commit here: mgmt.commit();
mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();
这将导致以下错误:

java.lang.NullPointerException 位于com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:52) 位于com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:18) 在java_util_concurrent_可调用$call.call(未知源) 位于org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) 位于org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110) 位于org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:114) 在groovysh_evaluate.run(groovysh_evaluate:3) 位于org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:215) 位于org.codehaus.groovy.tools.shell.Interpreter.evaluate(Interpreter.groovy:69) 位于org.codehaus.groovy.tools.shell.Groovysh.execute(Groovysh.groovy:185) 位于org.codehaus.groovy.tools.shell.shell.leftShift(shell.groovy:119) 位于org.codehaus.groovy.tools.shell.ShellRunner.work(ShellRunner.groovy:94)

我还将注意到,禁用和删除索引的例程也失败了

mgmt = graph.openManagement()
theIndex = mgmt.getGraphIndex('byUsername')
mgmt.updateIndex(theIndex, SchemaAction.DISABLE_INDEX).get()
mgmt.commit()
mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.DISABLED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();
m = graph.openManagement()
i = m.getGraphIndex('byUsername')
m.updateIndex(i, SchemaAction.REMOVE_INDEX).get()
m.commit()
19:26:26错误com.thinkaurelius.titan.graphdb.database.management.ManagementLogger-已收回[1@ac1f3fa810472-ip-172-31-63-1681]来自缓存,但等待事务关闭的时间太长。[StandardTitantTX[0x2314cd97]、StandardTitantTX[0x39f8adc0]、StandardTitantTX[0x09de1b85]上的过时事务警报

编辑2: 尝试在同一事务中创建新的属性键和索引确实有效!但这是否意味着我不能在现有属性键上创建索引

graph.tx().rollback();
mgmt = graph.openManagement();
indexName = 'byUsernameTest2';
propertyKeyName = 'testPropertyName2';
propertyKey = mgmt.makePropertyKey(propertyKeyName).dataType(String.class).cardinality(Cardinality.SINGLE).make();
mgmt.buildIndex(indexName,Vertex.class).addKey(propertyKey).buildCompositeIndex();
mgmt.commit();
graph.tx().commit();
mgmt.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();
mgmt.commit();
暂停后,这将导致:

mgmt = graph.openManagement();
index = mgmt.getGraphIndex('byUsernameTest2');
propkey = mgmt.getPropertyKey('testPropertyName2');
index.getIndexStatus(propkey);
此管理系统实例已关闭

尝试在以下位置获取新索引结果:

mgmt = graph.openManagement();
index = mgmt.getGraphIndex('byUsernameTest2');
propkey = mgmt.getPropertyKey('testPropertyName2');
index.getIndexStatus(propkey);
==>已启用


您需要等待Titan和DynamoDB注册索引。你可以这样做:

ManagementSystem.awaitGraphIndexStatus(graph, propertyKeyIndexName)
                    .status(SchemaStatus.REGISTERED)
                    .timeout(10, java.time.temporal.ChronoUnit.MINUTES) // set timeout to 10 min
                    .call();
默认超时时间通常不够长,因此您可以将其增加到10分钟,这通常在Dynamo后退时起作用

只有当索引处于已注册状态时,才能执行重新索引。一旦重新索引完成,您需要等待它被启用。通过重用上面的代码示例并将状态更改为ENABLED

有关更多信息,请参阅

编辑 让我来分享我一直在伯克利和迪纳摩DB后端工作的代码

    graph.tx().rollback(); //Never create new indexes while a transaction is active
    TitanManagement mgmt=graph.openManagement();
    PropertyKey propertyKey=getOrCreatePropertyKeyIfNotExist(mgmt, propertyKeyName);
    String indexName = makePropertyKeyIndexName(propertyKey);

    if (mgmt.getGraphIndex(indexName)==null) { 
        mgmt.buildIndex(indexName, Vertex.class).addKey(propertyKey).buildCompositeIndex();
        mgmt.commit(); // you MUST commit mgmt
        graph.tx().commit(); // and commit the transaction too
        ManagementSystem.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).call();
    }else { // already defined.
        mgmt.rollback();
        graph.tx().rollback();
    }

private static PropertyKey getOrCreatePropertyKeyIfNotExist(TitanManagement mgmt, String s) {
    PropertyKey key = mgmt.getPropertyKey(s);
    if (key != null)
        return key;
    else
        return mgmt.makePropertyKey(s).dataType(String.class).make();
}

private static String makePropertyKeyIndexName(PropertyKey pk) {
    return pk.name() + Tokens.INDEX_SUFFIX;
}
从我看到的错误来看,Titan似乎无法获取索引,这意味着您正在等待尚未定义的索引。查看导致错误的行


确保将正确的索引名传递给
waitgraphindexstatus

如果正在运行多个Titan实例,则应注意它们需要协调,然后索引才可用

此外,围绕交易管理以及在什么情况下交易将保持开放,存在各种微妙之处;我相信Titan 1.0.0在这方面没有TinkerPop的最新版本。您是否尝试过在引导后立即创建索引


最后,索引创建过程是不同的,这取决于之前是否使用过被索引的属性键。您是在尝试索引新键还是现有键?

谢谢您的回复。这返回了一个关于
ChronoUnit
的错误:
没有这样的属性:ChronoUnit for class:groovysh\u evaluate
使用Gremlin控制台时必须导入该类。我为您更新了答案。添加该步骤会导致
java.lang.NullPointerException
。我已经编辑了这个问题,以包含我粘贴到Gremlin中的确切命令。谢谢,但不幸的是,它不起作用。错误:
没有方法的签名:groovysh\u evaluate.getOrCreateIfNotExist()
。我正在传递一个字符串(属性的名称)作为第二个参数,因为
propertyKeyName
在任何地方都没有定义。我在Titan API文档中找不到这个函数。这在Gremlin shell中是否适用?请记住,这是Java代码,您可能需要对其进行一些更改,以使其在Gremlin控制台中运行;)我在一台计算机上运行一个实例