想象一下电子商务应用程序:
假设我有三个Node cluster
N1, N2, N3.
且我的一致性等级(CL)很弱:
那是
Read CL = N/2+1 = 2 (in this case), Write CL = Any (alteast 1)
我有一个产品表,例如
这是跨三个节点同步的初始数据
product_info : { 'computer': 1}
现在,客户端A从N1读取信息,客户端B从中读取信息 N2
客户端1看到1台计算机可用
客户端2看到1台计算机可用
他们现在都去购买客户A首先下订单。所以 N1,表格如下所示:
product_info : {'computer':0}
现在客户端2在N2处执行订单,表格看起来像 以下内容:
product_info : {'computer':0}
但实际上客户2的订单不应该被处理。
客户端C通过N3访问。现在读取在N1完成 返回0.(因为仲裁至少有2个节点应该响应)N3 值为1但其时间戳已过时。所以它会更新它 值并向客户显示没有可用的计算机。这很好
在此示例中,弱和强一致性级别都会导致错误的结果,这仅仅是因为在客户端A和B加载第一个product_info时,数据是同步的。如何在Cassandra中处理?
答案 0 :(得分:3)
您还没有提到复制因素。
如果您的读取一致性+写入一致性>复制因子,您将立即获得一致性。
让我们说你的复制因子是3.为了立即一致性和RC = 2,你需要WC至少2.如果你想要立即一致并且WC = 1,你的RC将需要是3.注意,这会严重影响可用性,因为一个节点关闭意味着你无法阅读。
立即一致意味着您将阅读所写的内容。即,在成功写入之后,没有读取将读取先前的值。但是,这并不会阻止您的应用程序使用之前读过的值。
在这种情况下,您可以使用轻量级事务。更新.....如果[某些情况。]。这将执行速度较慢,但可能足以满足您的使用情况。
通常,特别是在分布式场景中,最好处理失败 - 甚至将其作为商业案例 - 而不是试图阻止任何事情"坏"从永远发生。像这样的边缘案例是与业务交流的机会,并找到隐藏的机会:
我们甚至可以接受订单,让一位客户知道我们何时发现存在问题 - 我个人在亚马逊上看到了这一点。
如果我们绝对必须防止在卖出时出现任何超卖,那么也有一些模式。我们可以使用像raft甚至zookeeper这样的分布式锁来处理cassandra之外的协调。我们还可以为每个项目实现带有TTL的逻辑锁 - 使用TTL来确保混乱的代码不会弄乱库存。
这实际上取决于你想要什么样的保证,以及你为实现这个目标而愿意花多少钱。更重要的是,如果它更多无利可图不解决它。
希望有所帮助。