在分布式系统中,可能会发生不同类型的故障,例如,服务器可能会崩溃或永久故障,磁盘可能会损坏导致数据丢失,或者网络连接可能会丢失,导致系统的一部分无法访问。分布式系统如何对自身进行建模以从不同的可用资源中获得最大收益?帮助分布式系统在各种分布式特性之间选择理想平衡的指导原则是什么?
检查 Grokking the System Design Interview 以了解重要的分布式系统概念。
CAP 定理
CAP 定理指出,分布式系统不可能同时提供以下所有三个理想属性:
- 一致性(C):所有节点同时看到相同的数据。这意味着用户可以读取或写入系统中的任何节点并接收相同的数据。它相当于拥有一个最新的数据副本。
- 可用性(A):可用性是指系统中非故障节点收到的每个请求都必须产生响应。即使发生严重的网络故障,每个请求也必须终止。简单来说,可用性是指即使系统中的一个或多个节点出现故障,系统仍保持可访问性的能力。
- 分区容差(P):分区是系统中任意两个节点之间的通信中断(或网络故障),即两个节点都已启动但无法相互通信。即使系统中有分区,分区容错系统也会继续运行。这样的系统可以承受任何不会导致整个网络故障的网络故障。数据在节点和网络的组合之间得到充分复制,以使系统在间歇性中断时保持正常运行。
根据 CAP 定理,任何分布式系统都需要从三个属性中选择两个。三个选项是 CA、CP 和 AP。但是,CA 并不是一个真正的连贯选项,因为在网络分区的情况下,不能容忍分区的系统将被迫放弃一致性或可用性。因此,该定理实际上可以表述为:在存在网络分区的情况下,分布式系统必须选择一致性或可用性。
CAP 定理的证明
我们无法构建一个持续可用、顺序一致且能容忍任何分区故障的通用数据存储。我们只能构建具有这三个属性中的任意两个的系统。因为,为了保持一致,所有节点都应该以相同的顺序看到相同的更新集。但是,如果网络丢失了一个分区,则一个分区中的更新可能无法在客户端读取最新分区后从过期分区读取之前到达其他分区。应对这种可能性的唯一方法是停止为来自过期分区的请求提供服务,但随后该服务不再 100% 可用。
CAP 定理缺少什么?
我们无法避免分布式系统中的分区;因此,如上所述,根据 CAP 定理,分布式系统应该在一致性或可用性之间进行选择。 ACID(原子性、一致性、隔离性、持久性)数据库,例如 MySQL、Oracle 和 Microsoft SQL Server 等 RDBMS,选择一致性(如果无法与对等方检查,则拒绝响应)。相比之下,BASE(基本可用、软状态、最终一致)数据库,例如 MongoDB、Cassandra 和 Redis 等 NoSQL 数据库,选择了可用性(响应本地数据,但不确保它是最新的)。
CAP 定理沉默的一个地方是当没有网络分区时会发生什么?在没有分区的情况下,分布式系统有哪些选择?
救援 PACELC 定理
PACELC 定理指出,在复制数据的系统中:
如果存在分区(“P”),分布式系统可以在可用性和一致性(即“A”和“C”)之间进行权衡;
else(‘E’),当系统在没有分区的情况下正常运行时,系统可以在延迟(‘L’)和一致性(‘C’)之间进行权衡。
定理的第一部分(PAC)与CAP定理相同,ELC是扩展。整篇论文假设我们通过复制来保持高可用性。因此,当出现故障时,CAP 定理占上风。但如果不是,我们仍然需要考虑复制系统的一致性和延迟之间的权衡。
例子
- Dynamo 和 Cassandra 是 PA/EL 系统:它们在发生分区时选择可用性而不是一致性;否则,他们会选择较低的延迟。
- BigTable 和 HBase 是 PC/EC 系统:它们总是会选择一致性,放弃可用性和更低的延迟。
- MongoDB 可以被认为是 PA/EC(默认配置):MongoDB 在主要/次要配置中工作。在默认配置中,所有写入和读取都在主节点上执行。由于所有复制都是异步完成的(从主节点到辅助节点),当存在主节点丢失或在少数节点上被隔离的网络分区时,可能会丢失未复制到辅助节点的数据,因此会丢失分区期间的一致性。因此,可以得出结论,在网络分区的情况下,MongoDB 选择可用性但其他方面保证一致性。或者,当 MongoDB 配置为在多数副本上写入并从主副本上读取时,它可以归类为 PC/EC。
结论
CAP 和 PACELC 定理帮助分布式系统在各种分布式特性(如一致性、可用性、分区容限和延迟)之间选择理想的平衡。请查看 Grokking the System Design Interview 和 Grokking the Advanced System Design Interview 以获得一些系统设计基础知识的好例子。