当前位置: 首页 > 知识库问答 >
问题:

尽管QUORUM一致性级别与复制因子3不一致,但Cassandra不一致

侯博易
2023-03-14

我对卡珊德拉的一致性有疑问。我在集群中有3个Cassandra节点(版本2.0.14.352 ),我使用< b >一致性级别仲裁读取和写入,我的< b >复制因子是3。如果我理解replication_factor " >这个对我来说卡珊德拉应该是一致的,因为2 ^ 2

final Instant t1 = Instant.parse("2000-01-01T00:00:00.000Z");
final Instant t2 = Instant.parse("2000-02-01T00:00:00.000Z");

for (int i = 0; i < 100; i++) {
    dataProvider.setValue(t1, new Double(1));
    //If the next line is removed, the test will pass
    dataProvider.setValue(t2, new Double(3));

    dataProvider.saveToDB();
    dataProvider.clear();
    assertEquals("i=" + i, new Double(3), dataProvider.getValue(t2));
    assertEquals("i=" + i, new Double(1), dataProvider.getValue(t1));

    dataProvider.setValue(t1, new Double(2));
    dataProvider.saveToDB();
    dataProvider.clear();
    assertEquals("i=" + i, new Double(2), dataProvider.getValue(t1));

    dataProvider.setValue(t1, new Double(101));
    dataProvider.saveToDB();
    dataProvider.clear();
    assertEquals("i=" + i, new Double(101), dataProvider.getValue(t1));
}

与相应的表

CREATE TABLE keyspace.table(
  id text,
  year int,
  month int,
  time timestamp,
  value double,
  PRIMARY KEY ((id, year, month), time)
)

dataProvider.setValue()内部将给定值放入NavigableMap。dataProvider.saveToDB()将数据插入Cassandra。在这里,我一方面尝试异步插入数据,并等待所有ResultSetFuture完成,另一方面同步执行语句。但这只影响性能。详细来说,保存方法看起来像

final List<ResultSetFuture> sets = newLinkedList();
Batch batch = QueryBuilder.batch();
int batchsize=0;
for (Map.Entry<Instant, Double> entry : valueMap) {
    final Instant instant = entry.getKey();
    final ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("UTC"));
    final Date date = Date.from(instant);
    final Insert insert = QueryBuilder.insertInto(table)
            .value(ID, id)
            .value(YEAR, zonedDateTime.getYear())
            .value(MONTH, zonedDateTime.getMonthValue())
            .value(TIME, date)
            .value(VALUE, entry.getValue());
    batch.add(insert);
    ++batchsize;
    if(batchsize % 200 == 0){
        sets.add(cassandraConnector.executeAsync(batch));
        batch = QueryBuilder.batch();
    }
}
if(batchsize % 200 != 0) { //es gibt noch nicht abgeschickte Statements
    sets.add(cassandraConnector.executeAsync(batch));
}
cassandraConnector.waitForFinish(sets);

CassandraConnector管理连接。我正在等待所有ResultSets完成

public boolean waitForFinish(List<ResultSetFuture> sets) {
    ResultSet result = null;
    for (final ResultSetFuture resultSetFuture : sets) {
        // Wait until finished
        try {
            result = resultSetFuture.get();
        } catch (InterruptedException e) {
            resultSetFuture.cancel(true);
            e.printStackTrace();
            return false;
        } catch (ExecutionException e) {
            e.printStackTrace();
            if (result != null) {
                ExecutionInfo executionInfo = result.getExecutionInfo();
                System.out.println("Timout from server with IP: " + executionInfo.getTriedHosts());
            }
            return false;
        }
    }
    return true;
}

奇怪的是,如果我删除注释下面的行,测试就会通过,不管我执行它的频率是多少。但是如果我运行测试而不删除该行,有时它会在第一个循环中失败,但有时它会运行3个循环直到失败。此外,它总是在不同的行失败。例如

java.lang.AssertionError: i=0 
Expected :101
Actual   :2

我也得到了

java.lang.AssertionError: i=2
Expected :2
Actual   :101

所以看起来卡桑德拉写了1,之后卡桑德拉没有写2,而是恢复了我在1之前写的101。有人对这种行为有解释吗?如果我移除线,为什么测试会通过?我正在写不同的分区。我尝试将一致性级别更改为ALL,但是行为没有改变。

共有1个答案

马阳晖
2023-03-14

我解决了。显然,时钟不是100%同步的。在创建insert语句时,我添加了.using(timestamp(System.nanoTime()/1000));现在测试通过了。

 类似资料:
  • 想象一个电子商务应用程序: 假设我有三个并且我的一致性级别(CL)很弱:即 我有一个产品表,例如 这是跨三个节点同步的初始数据 > 现在,客户端A从N1读取信息,客户端B从N2读取信息 客户端1看到1台计算机可用 客户端 2 看到 1 台计算机可用 他们现在都去购买客户A先下订单。所以N1,表格如下所示: 现在客户端 2 下订单,因此在 N2 处,表将如下所示: 但实际上客户2的订单不应该被处理。

  • 我正在为我的应用程序创建一个cassandra会话对象,并为它创建一些准备好的语句。对每个准备好的语句设置不同的一致性级别。 我们之前只有statement1,cassandra读取延迟小于10ms。当我们添加statement2并从代码的一部分开始使用它时,每次cassandra调用的延迟都会增加到250ms。 这是datastax中的错误吗?有没有可能 正在将一致性级别设置为? 我错过了一些愚

  • 有人能帮助我如何通过datastax.cassandraconnector设置一致性吗?

  • 蒙戈 从这一资源中,我理解了为什么mongo不是基于以下陈述的 MongoDB支持“单主”模型。这意味着您有一个主节点和多个从节点。如果主人倒台,其中一个奴隶被选为主人。这个过程会自动进行,但需要时间,通常为10-40秒。在新领导人选举期间,您的副本集已关闭,无法进行写入 是否出于同样的原因,Mongo被称为(因为写入没有发生,所以返回系统中的最新数据),但不是(不适用于写入)? 在重新选择和写入

  • 问题内容: 我有以下对象: 我在以下使用它: 现在,树形图用于一个称为的类中,用于存储图形中当前存在的节点以及它们的边集(来自class )。我的问题是当我尝试执行时: 我有时会得到以下信息: 哈希码:true等于:true包含: false N:foo X:foo比较数:0 有人知道我在做什么错吗?我对这一切仍然是陌生的,所以如果我忽略了一些简单的事情,我会事先道歉(我知道这并不重要,但我想我会

  • 我试图在不一致的本体上运行一致性检查,Pellet和Hermit Reasoner没有给出不一致性。然而,Protege成功地标记了不一致的类。具体来说,我正在将SBVR规则更改为OWL2.0。所以我的规则是租车必须至少用3张信用卡投保;租车必须由至少5张信用卡投保; 相应的本体是 Hermit和Pellet将本体论标记为一致的,而AsProtege将这两个类标记为不一致的。 现在,如果我把我的S