什么时候数据一致性不是问题?

When is data consistency not an issue?

刚开始学习分布式系统,看了CAP定理,对Cassandra这样的AP系统很感兴趣

我的问题是在什么情况下你实际上可以牺牲一致性?实际上,我所说的是牺牲一致性意味着提供 不准确的数据。 在什么情况下您实际上会使用像 Cassandra 这样的 AP 数据存储?我想不出任何我不希望我的读数保持一致的情况。

通过 AP 系统,我假设您至少会以确保最终一致性为目标。

假设您正在开发一个社交网络,用户可以在其中拥有朋友和他们自己的新闻源。特定用户的提要是否偶尔有五分钟的延迟并不重要(他的提要列表具有最终一致性)。在这种情况下,新闻提要中缺少 2/3 的最新更新是可以接受的,只要这些提要最终会出现即可。事实上,Facebook 使用 Cassandra 构建了它的新闻提要。

想象一个分布式 key-value 存储缓存系统,其中更新非常少。如果几乎没有更新操作,保证强一致性是un-necessary,所以你可以专注于可用性。偶尔的缓存未命中(key-value 条目尚未填充)和由于最终一致性而对数据库的请求应该没问题。

My question is in what cases can you actually sacrifice consistency?

一个案例是构建推荐引擎数据集并使用 Cassandra 提供服务。这些数据集本质上是许多用户的聚合,以确定 purchasing/viewing 模式。

例如:如果我将 Rey Star Wars 人偶添加到我的购物车中,底层推荐引擎会根据其他购买了 Rey 人偶的人运行类似的购买模式查询。查询returns前5个产品结果,并将它们放在页面底部。

退回的这 5 件产品是对数千次先前购买的分析和汇总的结果。假设其中一些数据不一致,导致返回的 5 种产品出现差异。这真的很重要吗?

tl;dr; 真正要问的问题;在不到 10 毫秒内获得 5 个产品推荐的 somewhat-accurate 列表是否比在 100 毫秒内获得 100% 准确的 5 个产品推荐列表更好?

两个结果集都将有助于推动销售。但是返回速度足够快以至于不会影响用户体验的那个 much 更受欢迎。

CAP 中的

'C' 指的是线性化,这是一种非常强的一致性形式,大多数时候您不需要。

线性化是一种新近度保证,它使数据看起来只有一个副本。一旦您更改了数据,所有后续读取都将 return 更改的数据。这种级别的一致性代价高昂,而且无法很好地扩展。然而在某些情况下我们需要线性化,即

  1. 领导人选举
  2. 允许最终用户创建他们唯一的用户 ID
  3. 分布式锁等

当你有这些用例时,你会使用 ZooKeeper、etcd 等。Cassandra 也有轻量级事务 (LWT),它使用经典 Paxos 算法的扩展来实现线性化。此功能可用于解决那些必须具有线性化和可串行化的罕见用例,但它很昂贵。在绝大多数情况下,稍微弱一点的一致性就可以得到更好的可扩展性和性能。您用可扩展性和性能来换取一点一致性。

一些电子商务网站因无法履行订单而向客户发送道歉信。那是因为产品的最后一个副本由于缺乏和线性化而被卖给了多个客户。他们更愿意处理这个问题,而不是无法扩展客户群,也无法在严格的 SLA 中响应他们的请求。

据说 Cassandra 具有可调的一致性。您可能想要记录用户点击或活动以供分析。如果丢失了一些数据你没关系,但你不能在性能上妥协。您可能会使用 ANY 的写一致性级别并启用提示(草率的法定人数)。

如果您想要更高的一致性,您可以使用 QUORUM 一致性级别来读取和写入以及提示和读取修复。在绝大多数情况下,所有节点都会立即更新。即使一个或两个节点宕机,大多数节点都会有数据,并且故障节点会在它们恢复时使用提示、读取修复、反熵修复进行修复。

Cassandra 对于您不会对相同数据进行很多并发更新的情况特别有用。原因是,与发电机架构不同,它不使用矢量时钟来解决副本之间的冲突。相反,它使用基于时间戳的 Last Write Wins (LWW)。如果时间戳相同,则使用字典顺序。由于节点上的时间即使在 NTPD 存在的情况下也不会准确,因此存在数据丢失的可能性,尽管 Cassandra 已采取一些措施来避免这种情况 - 例如客户端时间戳而不是服务器端时间戳。

CAP 定理表示,给定分区容忍度,您可以在分布式数据库中选择可用性或一致性(无论如何都不会放弃分区容忍度)。所以如果你想拥有最大的可用性,你将不得不放弃一致性。这当然取决于业务的重要性。

您在 SO 上回答了一些问题,但是当您访问该页面时答案没有显示?可以忍受。所以情绪低落?不可能。关键的金融系统宁愿具有强一致性而不是可用性。每隔 once-in-a-while,当我尝试付款时,我银行的服务器就会离线。

通常,您选择可用性和最终一致性。你写到SO里的答案最终会出现。

除了上面提到的数据不一致的情况是可以容忍的,还有一些场景我们可以交给用户去解决。

例如,如果我们在数据库中发现了某人地址的两个不同版本,我们可以提示用户识别正确的地址。