使用 datastax java 驱动程序 4.10.0 在 Cassandra 上创建架构时重试查询时出现列族 ID 不匹配异常

Getting around Column family ID mismatch Exception when I retry the query while creating schema on Cassandra using datastax java driver 4.10.0

我编写了一段代码,当我的应用程序出现时,它会使用模式文件自动创建模式。有时在执行查询时我会得到一个 OperationTimedOutException 并且我已经为相同的地方编写了一个重试机制,如果我得到一个 OperationTimedOutException 我会重试查询。

现在,在使用多主机集群时,我的应用程序在创建新 table 时遇到了 OperationTimedOutException,并且代码重试了成功创建架构的查询,但在那之后我 org.apache.cassandra.exceptions.ConfigurationException: Column family ID mismatch

在做了一些研究后,我推测尽管我得到了一个 OperationTimedOutException 请求仍然在一个节点上的 Cassandra 中排队并且我的重试代码发送了另一个请求,该请求可能已经落在了不同的节点和这两个节点上使用不同的列族 ID 创建了他们的 table 版本,并且在架构传播时遇到不匹配。

Post 在创建 table 的情况下,我停止重试查询,而是继续获取​​键空间元数据并检查是否已创建 table。

try{
execute(cql);
}
 catch (QueryOperationTimedOutExcetpion e) {
                        if (isKeyspaceCreationStatement) {
                            boolean createdServerSide = false;
                            while (!createdServerSide) {

                           ThreadUtils.sleep(TimeUnit.SECONDS.toMillis(5000));

                           KeyspaceMetadata keyspaceMetadata = getValueFromOptional(sessionToUse.getMetadata().getKeyspace(keyspace));
                           String cleanedKeyspaceExport = keyspaceMetadata.describeWithChildren(false).toLowerCase().replaceAll("\n", "");
}

这工作了一段时间,然后我将我的 datastax 驱动程序从 3.1.3 升级到 4.10.0,这删除了 ​​OperationTimedOutException 并引入了 DriverTimeoutException,如果客户端没有从服务器。 但是 post 这次升级我卡在了上面提到的代码上,因为 table 永远不会被创建。据我了解,当客户端没有从服务器获得响应时,DriverTimeoutException 和 OperationTimedOutException 都会返回,但是为什么 table 永远不会被创建。在这个问题之前我应该​​怎么做?

编程模式创建在分布式系统(例如 Cassandra)中可能很危险。您看到的是所谓的“Schema 分歧”,并且需要documentation 中所述的管理干预。发生这种情况是因为 creation/deletion of keyspaces/tables/... 的代码被发送到一个节点,然后传播到其他节点 - 与“正常”操作相反,它不遵守一致性级别等 - 这是完全不同的机制。

为避免架构不一致,您需要:

  • 如果您发送多个 DDL 语句,它们都需要发送到同一个节点,以避免将下一个语句发送到另一个可能尚未更新架构的节点。
  • 您需要等到集群中的所有节点都同意模式 - 这应该在发送下一个 DDL 或执行数据操作之前完成。这是通过检查 DDL 执行结果的 getExecutionInfo().isSchemaInAgreement() 或通过在会话对象上调用 .checkSchemaAgreement()(参见 documentation
  • 来完成的