cassandra中的一致性级别调整

cassandra中的一致性级别调整,cassandra,consistency,eventual-consistency,Cassandra,Consistency,Eventual Consistency,设想一个电子商务应用程序: 假设我有三个节点集群N1、N2、N3.并且我的一致性级别(CL)很弱: 就是 Read CL=N/2+1=2(在本例中),Write CL=Any(alteast 1) 我有一个产品表,如 这是跨三个节点同步的初始数据 product_info : { 'computer': 1} 现在客户端A从N1读取信息,客户端B从N1读取信息 氮气 客户端1看到1台计算机可用 客户端2看到1台计算机可用 他们现在都去购买客户A,先下单。所以 N1,该表将如下所示: 产品信息

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

假设我有三个
节点集群
N1、N2、N3.
并且我的一致性级别(CL)很弱: 就是

Read CL=N/2+1=2(在本例中),Write CL=Any(alteast 1)

我有一个产品表,如

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

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

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

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

  • 他们现在都去购买客户A,先下单。所以 N1,该表将如下所示:

    产品信息:{'computer':0}

  • 现在客户机2下了订单,所以在N2,表将如下所示 以下是:

    产品信息:{'computer':0}

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

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

    在本例中,弱一致性级别和强一致性级别都将导致错误的结果,这仅仅是因为在客户端A和B加载第一个产品信息时,数据是同步的。在卡桑德拉如何处理


  • 你没有提到你的复制因素

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

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

    立即的一致性意味着你将阅读所写的任何东西。i、 e.成功写入后,将不会读取以前的值。但是,这并不阻止应用程序使用以前读取的值

    在这种情况下,您可以使用轻量级事务。更新。。。。。如果[某些条件]。这将执行得较慢,但对于您的用例来说可能已经足够了

    通常情况下,特别是在分布式场景中,更好的做法是处理失败——甚至将其作为一个业务案例——而不是试图阻止任何“坏”的事情发生。像这样的边缘案例是与企业对话并发现隐藏机会的机会:

    • 如果我们超额预订了一件物品会发生什么
    • 最好是取消订单,或者让客户知道他们的订单不可避免地被延迟,可能是进行销售并给他们一张礼券
    • 我们能给客户提供一台稍微好一点的电脑吗?这会对利润产生轻微的影响吗?这可以帮助我们进行销售,让客户满意,并可能给我们带来退货业务。戴尔经常这样做
    • 我们能否打电话给客户并解释可能增加销售的情况
    我们甚至可以接受订单,并在发现问题时通知一位客户——我个人在亚马逊看到过这一点

    如果我们绝对必须在销售时防止任何过度销售,那么也有相应的模式。我们可以使用一个分布式锁来处理卡桑德拉之外的协调工作,比如筏式锁,甚至是动物园管理员。我们还可以为每个项目使用TTL实现逻辑锁——使用TTL确保凌乱的代码不会打乱库存

    这实际上取决于你想要一个怎样的保证,以及你愿意为实现这一目标而经历多少麻烦。更重要的是,如果不解决它不是更有利可图的话


    希望这能有所帮助。

    在写入过程中,立即保持一致性会发生什么:假设三分之二的节点没有网络。客户端的写操作是否成功?我的意思是写在客户端级别失败,因为他被指示。但是一个节点(三个节点中的一个)过度写入了该值。如果WC为2,则至少两个副本必须确认写入,客户端才能接收成功。因此,如果一个分区的两个副本节点在复制因子为3的情况下停机,如果指定了WC=2,则写入将失败。这与读取的情况类似-n=RC节点必须响应才能成功读取。这是一种交易可用性以获得一致性的方法。就客户而言,写入失败。但其中一个节点已写入该值,并且没有回滚功能。因此,当失败的节点返回时,它通过流言获取最新的值。当查询实际执行时,客户端认为它好像失败了。我可能是错的,但似乎没有应用不成功的提交。只需设置一个集群,并尝试该场景。似乎没有从任何节点返回“未成功”的写入,即使是读取一致性为1的节点。现在这可能是因为协调器已经知道副本已关闭,并且没有发出写操作…我将尝试找到确切原因,如果总是这样。更新:我的演示“工作”的原因似乎是因为有关关闭节点的信息通过流言传播,如果协调器知道节点停机,它就不会发出请求。如果发送了请求,那么一个节点死亡,那么您描述的场景就可能发生。对客户端写入失败的建议是重试。这通常是可以的,因为插入和更新基本上是成功的。不过要小心,我会反击的。所使用的变通方法无疑将取决于您的用例和所需的保证级别。