2

想象一个电子商务应用程序:

假设我有三个Node cluster N1, N2, N3.并且我的一致性级别 (CL) 很弱:那就是

Read CL = N/2+1 = 2 (in this case), Write CL = Any (alteast 1)

我有一个产品表,例如

这是跨三个节点同步的初始数据

 product_info : { 'computer': 1}
  1. 现在客户端 A 从 N1 读取信息,客户端 B 从 N2 读取信息

    客户端 1 看到 1 台计算机可用

    客户端 2 看到 1 台计算机可用

  2. 现在他们俩都去买了,客户A先下订单。所以 N1,表格将如下所示:

    product_info : {'computer':0}

  3. 现在客户 2 在 N2 下订单,表格如下所示:

    product_info : {'computer':0}

    但实际上客户 2 的订单不应该被处理。

  4. 客户端 C 通过 N3 访问。现在在 N1 完成读取,返回 0。(因为 quorum 至少有 2 个节点应该响应)N3 的值为 1,但其时间戳已过时。因此它将更新其值并向客户端显示没有可用的计算机。这很好

    在这个例子中,无论是弱一致性级别还是强一致性级别都会导致错误的结果,仅仅是因为客户端 A 和 B 加载第一个 product_info 时,数据是同步的。这在 Cassandra 中如何处理?

4

1 回答 1

3

你还没有提到你的复制因子。

如果您的读取一致性 + 写入一致性 > 复制因子,您将立即获得一致性。

假设您的复制因子为 3。对于即时一致性和 RC = 2,您将需要 WC 至少 2。如果您想要即时一致性并且 WC = 1,您的 RC 将需要为 3。请注意,这会严重影响可用性,因为一个节点出现故障意味着您无法阅读。

即时一致性意味着您将阅读所写的任何内容。即成功写入后,不会读取之前的值。但是,这不会阻止您的应用程序使用它之前读取的值。

在这种情况下,您可以使用轻量级事务。更新.....如果[某些情况。]。这将执行较慢,但可能足以满足您的用例。

很多时候,特别是在分布式场景中,最好处理失败——甚至将其作为商业案例——而不是试图阻止任何“坏事”的发生。像这样的边缘案例是与业务对话的机会,并发现隐藏的机会:

  • 如果我们超量预订商品会怎样?
  • 是取消订单更好,还是让客户知道他们的订单不可避免地被延迟了,可能会进行销售并给他们一张礼券。
  • 我们可以给客户一台稍微好一点的电脑,但利润会受到轻微影响吗?这可以帮助我们进行销售,让客户满意,并可能给我们带来回报。戴尔经常这样做。
  • 我们可以打电话给客户并解释可能的追加销售情况吗?

当我们发现有问题时,我们甚至可以接受订单并让一位客户知道——我个人在亚马逊上看到了这一点。

如果我们绝对必须在卖出时防止任何超卖,那么也有这样的模式。我们可以使用 raft 甚至 zookeeper 之类的分布式锁来处理 cassandra 之外的协调。我们还可以为每个项目实现带有 TTL 的逻辑锁——使用 TTL 来确保杂乱的代码不会弄乱库存。

这实际上取决于您想要的保证方式,以及您愿意为此付出多少麻烦。更重要的是,如果解决它不是有利可图。

希望有帮助。

于 2014-07-24T21:18:06.270 回答