在现有键空间上使用cqlsh创建新表:列族ID不匹配

时间:2015-03-13 11:07:10

标签: cassandra schema cqlsh

休斯顿,我们遇到了问题。

尝试在现有的Cassandra(v2.1.3)键空间上创建一个带有cqlsh的新表,结果是:

ServerError: 
<ErrorMessage code=0000 [Server error] message="java.lang.RuntimeException:
java.util.concurrent.ExecutionException: 
    java.lang.RuntimeException:      
        org.apache.cassandra.exceptions.ConfigurationException: Column family ID mismatch (found e8c03790-c952-11e4-a753-5981ea73cd7c; expected e8b14370-c952-11e4-a844-8f10bfb9c386)">

在第一次创建尝试后,再次尝试将导致:

AlreadyExists:表'ks.metrics'已存在

但是检索密钥空间desc tables;的现有表列表将不会报告新表。

该问题似乎与Cassandra-8387有关,只是只有一个客户尝试创建该表:cqlsh

我们确实有一堆Spark作业会在启动时创建键空间和表,可能并行执行此操作。这会导致密钥空间损坏吗?

创建一个新的密钥空间并向其中添加一个表按预期工作。

有什么想法吗?

更新

找到一种解决方法:在密钥空间上发布修复,表格将显示(desc tables)并且也可以正常运行。

2 个答案:

答案 0 :(得分:8)

简短回答: They have a race condition,他们认为他们已经解决了 1.1.8 ......

答案很长:

我在其中一个群集上一直收到该错误。我有测试机器的硬盘速度非常慢,当我在两台独立的计算机上有4个节点时,创建一个或两个表就足以得到错误。

下面我从Cassandra 3.7安装中获得了堆栈跟踪的副本。虽然您的版本是2.1.3,但我会惊讶于这部分代码发生了很大变化。

正如我们所看到的,异常发生在validateCompatibility()函数中。这要求MetaData的新旧版本具有相同的内容:

  • ksName(键空间名称)
  • cfName(columnfamily name)
  • cfId(columnfamily UUID)
  • flags(isSuper,isCounter,isDense,isCompound)
  • 比较器(键排序比较器)

如果这些值中的任何一个在旧元数据和新元数据之间不匹配,则该进程会引发异常。在我们的例子中,cfId值不同。

向上移动,我们立即调用apply() validateCompatibility()

接下来我们有updateTable()。同样,它几乎立即调用apply()。首先,它调用getCFMetaData()来检索将与新数据进行比较的当前列族数据(&#34; old&#34;)。

接下来我们看到updateKeyspace()。该函数计算diff以了解更改的内容。然后它将其保存在每种类型的数据中。表格在Type ...后面排名第二

在此之前,他们有mergeSchema()来计算Keyspace等级的变化。然后删除已删除的键空间,并为更新的键空间(以及新的键空间)生成新的键空间。最后,它们遍历为每个键空间调用updateKeyspace()的新键空间。

接下来在堆栈中我们看到了一个有趣的函数:mergeSchemaAndAnnounceVersion()。一旦在内存和磁盘上更新了密钥空间,这个版本将更新版本。架构的版本包括不兼容的cfID,从而生成异常。 Announce部分是向其他节点发送一个八卦消息,告知该节点现在知道某个模式的新版本。

接下来我们看到名为MigrationTask的内容。这是用于在Cassandra节点之间迁移更改的消息。消息有效负载是一组突变(由mergeSchema()函数处理的突变。)

堆栈的其余部分只显示run()函数,这些函数是用于处理消息的各种函数类型。

在我的情况下,对我来说,问题会在稍后解决,一切都很顺利。我最终无法与模式进行同步。正如所料。但是,它阻止我一次创建所有表。所以,我的看法是迁移消息没有按预期的顺序到达。必须有一个超时,通过重新发送事件并产生混淆来处理。

所以,让我们先看看发送消息的代码,你在MigrationManager中看到了一个。在这里,我们有一个MIGRATION_DELAY_IN_MS参数与旧问题Schema push/pull race相关联,这是为了避免竞争条件。嗯......你走了。因此他们意识到存在可能的竞争条件,并试图避免它,他们在那里增加了一点延迟。该修复程序的一部分包括版本检查。如果版本已经相等,请完全避免更新(即忽略那个八卦)。

if (Schema.instance.getVersion().equals(currentVersion))
{
    logger.debug("not submitting migration task for {} because our versions match", endpoint);
    return;
}

我们谈论的延迟是一分钟:

public static final int MIGRATION_DELAY_IN_MS = 60000;

有人会认为一分钟就足够了,但不知怎的,我仍然会一直得到错误。

事实上,他们的代码并不期望一个接一个地发生多个变化,包括像我这样的大延迟。因此,如果我要创建一个表,然后做其他事情,我会很好。另一方面,当我想在那些慢速机器上连续创建20个表时,来自先前模式更改的闲聊消息迟到(即在新的CREATE TABLE命令到达该节点之后)。这是什么时候我收到了这个错误。我猜,最糟糕的部分是它是一个虚假的错误(即它告诉我八卦是后来的,而不是我的架构无效,而且八卦消息中的架构是旧的。)

org.apache.cassandra.exceptions.ConfigurationException: Column family ID mismatch (found 122a2d20-9e13-11e6-b830-55bace508971; expected 1213bef0-9e
    at org.apache.cassandra.config.CFMetaData.validateCompatibility(CFMetaData.java:790) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.config.CFMetaData.apply(CFMetaData.java:750) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.config.Schema.updateTable(Schema.java:661) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.updateKeyspace(SchemaKeyspace.java:1350) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.mergeSchema(SchemaKeyspace.java:1306) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.schema.SchemaKeyspace.mergeSchemaAndAnnounceVersion(SchemaKeyspace.java:1256) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.service.MigrationTask$1.response(MigrationTask.java:92) ~[apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.net.ResponseVerbHandler.doVerb(ResponseVerbHandler.java:53) [apache-cassandra-3.9.jar:3.9]
    at org.apache.cassandra.net.MessageDeliveryTask.run(MessageDeliveryTask.java:64) [apache-cassandra-3.9.jar:3.9]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_111]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]

答案 1 :(得分:0)

我有两个不同的表模式,错误地使用了相同的表名。所以这个问题发生了(我正在使用express-cassandra