第九章:一致性与共识

DDIA9-1.png

构建容错系统的最好方法,是找到一些带有实用保证的通用抽象,实现一次,然后让应用依赖这些保证。比如事务。 我们需要了解系统能力的边界:哪些可行,哪些不可行。

一致性保证

分布式系统的时序问题:

  • 在同一时刻查看两个数据库节点,则可能在两个节点上看到不同的数据,因为写请求在不同的时间到达不同的节点。
  • 无论数据库使用何种复制方法(单主复制,多主复制或无主复制),都会出现这些不一致情况。
  • 大多数复制的数据库至少提供了最终一致性,这意味着如果你停止向数据库写入数据并等待一段不确定的时间,那么最终所有的读取请求都会返回相同的值。
  • 换句话说,不一致性是暂时的,最终会自行解决(假设网络中的任何故障最终都会被修复)。最终一致性的一个更好的名字可能是收敛(convergence),因为我们预计所有的副本最终会收敛到相同的值。
  • 最终一致性是非常弱的保证——没有说什么时候会收敛。
  • 在与只提供弱保证的数据库打交道时,你需要始终意识到它的局限性,而不是意外地作出太多假设。(始终不信任它)
  • 除了最终一致性,有没有更强的一致性模型?

  • 分布式一致性模型
  • 分布式一致性模型和我们之前讨论的事务隔离级别的层次结构有一些相似之处。
  • 不同:事务隔离主要是为了避免由于同时执行事务而导致的竞争状态,而分布式一致性主要关于在面对延迟和故障时如何协调副本间的状态。
  • 线性一致性

    线性一致性的想法?

  • 数据库可以提供只有一个副本的假象(即,只有一个数据副本),那么每个客户端都会有相同的数据视图,且不必担心复制滞后了。
  • 线性一致性(linearizability),也称为原子一致性(atomic consistency),强一致性(strong consistency),立即一致性(immediate consistency) 或外部一致性(external consistency )。
  • 线性一致性提供了什么保证?

  • 只要一个客户端成功完成写操作,所有客户端从数据库中读取数据必须能够看到刚刚写入的值。
  • 系统应保障读到的值是最近的、最新的,而不是来自陈旧的缓存或副本。
  • 线性一致性是一个新鲜度保证(recency guarantee)。
  • 图9-1 这个系统是非线性一致的,导致了球迷的困惑 DDIA9-2.png

    如何使得系统线性一致?