【问题标题】:Cassandra concurrent writesCassandra 并发写入
【发布时间】:2017-06-14 02:45:07
【问题描述】:

当并发写入发生时,Cassandra 如何保证最终的一致性?

例如,客户端 A 写入 tableA.rowA.colA,同时客户端 B 写入 tableA.rowA.colA。

协调节点将请求分发给副本节点,例如 NodeA、NodeB 和 NodeC。

在 NodeA 上,ClientA 请求首先到达。 在 NodeB 上,ClientB 请求首先到达。 那么,它会永远不一致吗?

【问题讨论】:

    标签: cassandra eventual-consistency nosql


    【解决方案1】:

    Cassandra 遵循“最后写入获胜”政策。使用的时间戳可以手动设置,但默认情况下由请求者see Datastax Java Driver docs 设置客户端。写入到达的顺序无关紧要。如果写 A 的时间戳比写 B 早,那么它总是会被写 B 覆盖。唯一不明确的情况是时间戳完全匹配。在这种情况下,更大的值获胜。

    最终一致的部分是:

    • 假设 A 的时间戳早于 B
    • 如果 A 到达 Replica 1,B 到达 Replica 2,正确的状态是 B
    • Replica 1 会响应 A,直到从 Replica 2 收到关于 B 的信息
    • 当 B 被复制时,副本 1 也会响应 B。

    大多数用例涉及不在 Cassandra 中存储状态,因此不会出现此类问题。

    【讨论】:

    • 好的,所以时间戳在到达任何副本机器之前设置。因此,请确保同一客户端的所有更新请求都具有相同的时间戳。
    • 客户端如何同步他们的时间戳?就像不同的服务器有不同的当地时间。
    • 通常是NTP,但更重要的是建立一个数据模型,使不同的客户端不同步时间不会破坏数据。
    【解决方案2】:

    每次写入(插入/更新/删除)到 cassandra,都会插入与每列关联的时间戳。当您执行读取查询时,时间戳用于在单个列或集合元素中选择“获胜”更新

    如果我有一个具有相同时间戳的真正并发写入怎么办?在不太可能的情况下,您最终会得到两个在其微秒内匹配的时间戳,您最终可能会得到一个错误的版本,但 Cassandra 通过比较字节值来确保始终打破联系

    所以对于您的情况 “在 NodeA 上,ClientA 请求首先到达。在 NodeB 上,ClientB 请求首先到达”

    • 如果 ClientA 请求时间戳较旧,则 ClientA 将获胜

    • 如果 ClientB 请求时间戳较旧,则 ClientB 将获胜。

    • 如果 ClientA 和 ClientB 都具有相同的时间戳,则通过按字节按词法比较值来选择获胜者,因此返回的值是确定性的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 2020-10-06
      • 2016-05-31
      • 2013-01-13
      • 2017-06-03
      相关资源
      最近更新 更多