【问题标题】:Strong Consistency in CassandraCassandra 中的强一致性
【发布时间】:2018-06-17 11:12:17
【问题描述】:

根据datastax文章,可以保证强一致性 如果,R + W > N 在哪里 R 是读操作的一致性级别 W是写操作的一致性级别 N是副本数

这里的强一致性是什么意思?这是否意味着“每次”从数据库中给出查询的响应,响应将“始终”是最后更新的值?如果在cassandra中保持强一致性的条件,那么,是不是就没有返回数据可能不一致的场景呢?简而言之,强一致性是否意味着100%一致性?

编辑 1

添加一些关于即使 R+W>RF 时 Cassandra 可能不一致的场景的额外材料

  1. Write fails with Quorum CL
  2. Cassandra's eventual consistency

【问题讨论】:

    标签: cassandra cassandra-3.0


    【解决方案1】:

    Cassandra 具有可调的一致性,您可以选择一些折衷方案。

    R + W > N - 这只是意味着您的往返行程中必须有一个重叠节点,该节点具有可用的实际和最新数据以保持一致。

    例如,如果您在 CL.ONE 处写入,则需要在 CL.ALL 处读取以确保获得一致的结果:N+1 > N - 但您可能不想要 CL.ALL,因为您不能容忍集群中的单节点故障。

    通常您可以在读写时选择 CL.QUORUM 以确保一致性并容忍节点故障。例如,在 RF=3 时,QUORUM 需要 (3/2)+1=2 个可用节点,因此 R+W>N 将是 4>3 - 您的请求是一致的,并且您可以容忍单个节点故障。

    要记住一件事 - 在所有节点(cassandra 和应用程序)上拥有同步时钟非常重要,您需要启动并运行 ntp。

    【讨论】:

    • 射频是什么意思?
    • @DarkSkull RF == 复制因子
    【解决方案2】:

    是的。如果 R + W 一致性大于副本,那么您将始终获得一致的数据。 100% 一致性。但是您必须牺牲可用性以实现更高的一致性。

    Cassandra 具有可调一致性的概念(基于查询设置一致性)。

    【讨论】:

    【解决方案3】:

    对于读取和写入,ANY、ONE、TWO 和 THREE 的一致性级别被认为是弱的,而 QUORUM 和 ALL 被认为是强的。

    【讨论】:

      【解决方案4】:

      虽然这是一个老问题,但我想我会插话来澄清事实。

      R+W>RF 并不意味着强一致性

      具有 **R+W>RF* 的系统只会最终保持一致。在节点故障期间或写入之间,强一致性保证的声明中断。例如考虑以下场景:

      假设有 3 个节点 A、B、C,RF=3、W=3、R=2(因此,R+W = 5 > 3 = RF)

      进一步假设键 k 与值 v 相关联,即 (k,v) 存储在数据库中。假设发生以下一系列动作:

      • t=1:(k,v1) 写请求从用户发送到 A,B,C
      • t=2:(k,v1) 到达 A 并写入存储在 A
      • t=3:Reader 1 发送对密钥 k 的读取请求,由 A 和 B 回复
      • t=4:阅读器 1 收到响应 (k,v1) - 根据最新的写入获胜规则
      • t=5:Reader 1 发送另一个读取请求,由节点 B 和 C 提供服务
      • t=6:阅读器 1 收到响应 (k,v),这是一个较旧的值 INCONSISTENCY
      • t=7:(k,v1) 到达 C 并写入存储在 C
      • t=8:(k,v1) 到达 B 并写入存储在 B

      这说明W+R>RF不能保证强一致性。为了确保强一致性,您可能需要使用另一种算法,例如 paxosraft,这有助于确保写入是原子的。 您可以在同一here 上阅读一篇有趣的文章(请查看常见问题解答部分)


      编辑

      Cassandra 确实有一些内部机制(称为阻塞读取修复)——在来自数据库的响应发送回客户端之前触发同步写入。这种同步读取修复发生在被查询的节点之间不一致的情况下,以实现读取一致性级别并确保称为单调读取一致性 [参见下面的定义]。这会导致上例中的 (k,v1) 在第一次读取请求的情况下返回响应之前写入节点 B,因此第二次读取请求也将具有更新的值。 (感谢@Nadav Har'El 指出这一点)

      但是,这仍然不能保证强一致性。以下是一些清除它的定义:

      顺序/强一致性:任何执行的结果都是一样的,就好像读取和写入按某种顺序发生一样,并且每个单独的处理器的操作按照指定的顺序出现在这个顺序中它的程序 [由 Leslie Lamport 定义]

      单调读取一致性:一旦读取一个值,所有后续读取都将返回该值或更新版本

      顺序一致性要求客户端程序/读取器查看写入的最新值,因为写入语句在程序指令序列中的读取语句之前执行。

      【讨论】:

      • 你错了。您所期望的“一致性”称为“单调读取”(即,在已经读取新值之后永远不会读取旧值)并且 Cassandra 实际上确实支持它!在步骤 t=3 中,当协调器从 A 和 B 接收并发现它们不同时,它会协调(以生成要在 t=4 中返回的结果)但也将协调后的结果同步发送给 A 和 B(不是在读取完成之前返回)。因此,当读取完成时,返回 (k,v1),此数据同时在 A 和 B 上。下一次读取,无论选择哪两个节点,也将返回 (k,v1)。
      • @NadavHar'El “如果:所有并行进程(或节点、处理器等)以相同的顺序(按顺序)看到所有访问,则据说该协议支持强一致性” - 来自维基百科。因此,强(顺序)一致的系统必须具有单调读取一致性。如果违反了MR,那么强一致性就没有意义了。
      • Cassandra 有两个不同的特性。一种是概率读取修复,它有时在达到 CL 后在后台运行。另一种是和解。当协调器在实现 CL 之前从不同的副本接收到不同的数据时,就会发生这种情况。然后,Cassandra 将协调后的数据写回 - 并等待完成写入。关于多 DC(Cassandra 不等待其他 DC 上的写入)和 CL(写入应该有哪个 CL?)存在一些微妙的问题,但他们并没有简单地忘记处理这个问题。 issues.apache.org/jira/browse/CASSANDRA-2494
      • @NadavHar'El 谢谢。将 CL 作为 Quorum 读取意味着在这种情况下需要写入 CL 的 quorum 以实现一致性,不是吗?另外,如果跨数据中心的读修复不是同步的,这是否意味着一致性保证在这里被打破了?
      • 虽然我在某种程度上是 Cassandra 专家(参与了将其重写为 C++,即 ScyllaDB),但我不记得所有细节,您可能想询问更大的专家,或检查代码。如果我没记错的话,无论读取 CL 如何,协调都会等待 LOCAL_QUORUM 写入成功,这对于 QUORUM 写入来说已经足够了。是的,如果我没记错的话,阅读单调性在 DC 之间被打破了。不一定非要这样,它只是为了避免非常高的延迟而采取的捷径......
      猜你喜欢
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2015-06-05
      • 2021-11-24
      • 2014-10-13
      • 2015-08-08
      • 2017-02-23
      • 1970-01-01
      相关资源
      最近更新 更多