【问题标题】:ScyllaDB: Running CQL query on different nodes in the Scylla cluster gives different resultsScyllaDB:在 Scylla 集群中的不同节点上运行 CQL 查询会产生不同的结果
【发布时间】:2022-07-11 22:18:28
【问题描述】:

我正在使用 Scylla 版本 4.6.3。我在单个 DC 中有一个由 3 个节点组成的集群。我已按照https://docs.scylladb.com/operating-scylla/procedures/cluster-management/add-dc-to-existing-dc/ 中的说明在新 DC 中添加 3 个新节点。新 DC 中的节点启动后,我检查 nodetool 状态并确保所有节点都已启动并运行。现在由于所有节点都是同一个集群的一部分,我假设查询结果应该是相同的,无论我在哪个节点上运行 cql 查询,不是吗?但是我看到当查询在不同的节点上运行时数据是不同的。事实上,在同一个 DC 的不同节点上查询时,查询结果也是不同的!观察到以下差异(虽然这不是一个完整的列表):

  1. 在 N1 上,一些主键没有记录,但在 N2 上,同一主键有几条记录。
  2. 在 N1 上,记录计数显示的值与在 N2 上不同。
  3. 在同一 DC 中的不同节点之间以及跨 DC 中都可以观察到这种差异。

    我的密钥空间之前使用了复制因子为 2 的 SimpleStrategy。在添加新 DC 时,作为文档中描述的步骤的一部分,我对其进行了修改,以在两个 DC 中使用复制因子为 2 的 NetworkTopologyStrategy:

    ALTER KEYSPACE ks WITH replication = { \'class\' : \'NetworkTopologyStrategy\', \'existing-dc\' : 2, \'new-dc\' : 2};
    

    为什么会有这种差异?我错过了什么?这是一个示例键空间和表定义:

    CREATE TABLE ks.cf (
        hourofyear int,
        operationtime bigint,
        action text,
        entityid text,
        entitytype text,
        operatorid text,
        PRIMARY KEY (hourofyear, operationtime)
    ) WITH CLUSTERING ORDER BY (operationtime DESC)
        AND bloom_filter_fp_chance = 0.01
        AND caching = {\'keys\': \'ALL\', \'rows_per_partition\': \'ALL\'}
        AND comment = \'\'
        AND compaction = {\'class\': \'LeveledCompactionStrategy\'}
        AND compression = {\'sstable_compression\': \'org.apache.cassandra.io.compress.LZ4Compressor\'}
        AND crc_check_chance = 1.0
        AND dclocal_read_repair_chance = 0.0
        AND default_time_to_live = 0
        AND gc_grace_seconds = 864000
        AND max_index_interval = 2048
        AND memtable_flush_period_in_ms = 0
        AND min_index_interval = 128
        AND read_repair_chance = 0.0
        AND speculative_retry = \'99.0PERCENTILE\';
    CREATE INDEX auditid ON ks.cf (entityid);
    CREATE INDEX agentid ON ks.cf (operatorid);
    CREATE INDEX auditaction ON ks.cf (action);
    

    示例查询:

    select count(*) from ks.cf where hourofyear = 4444;
    

    此查询在不同的运行(即使在同一分钟内)给出不同的结果。有时它在所有 ndo 上显示相同的结果。数据不再写入此键空间。为什么我在多次运行中看到这种差异?

    cqlsh> select count(*) from ks.cf where hourofyear = 4446;
    
     count
    -------
      1072
    
    cqlsh> select count(*) from ks.cf where hourofyear = 4446;
    
     count
    -------
      1545
    

    两次运行仅相隔几秒钟。为什么有区别?有人可以对此有所了解吗?

    标签: scylla


    【解决方案1】:

    你没有提到你最后一次在这个集群上运行nodetool repair(或使用 Scylla Manager 运行修复)是什么时候。

    ScyllaDB(以及 Cassandra)使用最终一致性,这意味着您的写入请求将在达到该请求的一致性级别 (CL) 时得到满足。

    如果您使用 CL=ONE 进行写入,则只有 1 个副本需要 ACK 才能让应用程序认为这是成功的。到第二个副本的复制将同步完成(也可能由于各种原因而失败)。

    这里是反熵机制,你可以在这里阅读更多关于它们的信息: https://docs.scylladb.com/architecture/anti-entropy/

    您必须确保您的集群在表的 gc_grace_seconds 值之前完成集群范围的修复(默认 10 天)

    您还应该在添加第二个 DC 之前完全修复您的集群,或者至少在添加第二个 DC 之后完成它。这也写在我们的文档中。

    最重要的是,您正在运行 CQL 查询,除非您更改了 CQL 查询 CL,否则它将使用默认的 CL=ONE。 这意味着集群中的每个副本(来自 2 个 DC 中的任何一个)都可以响应您的读取请求,并且如上所述,当前数据很可能不一致。

    在此处阅读有关架构的更多信息 -> Ring Architecture / CL:https://docs.scylladb.com/architecture/console-CL-full-demo/ https://docs.scylladb.com/architecture/ringarchitecture/

    我强烈建议您访问 Scylla 大学,了解我在这里写的所有内容以及更多信息:https://university.scylladb.com/courses/scylla-essentials-overview/lessons/architecture/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-06
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多