在一个大型分布式系统中,不可能在任何时候都实现一致性、可用性和分区容错性差,Brewer 定理已经说明了这一点。然而,为了快速和直观的说明,我使用一个简单的例子来解释中心思想,如图9-3和9-4所示。
图9-3和9-4显示了集群系统的两个节点,其中处理 A 和 B 分别从 X 和 X’访问数据。X 和 X’是复制的数据存储区(或结构) ,并保存相同数据集的副本。
A 写入 X,B 读取 X’。X 和 X 之间同步。V 是存储在 X 和 X’中的实体或对象。V 有一个初始值 v0。
图9-3显示了一个成功的用例,其中 A 写 v1到 V (从 v0更新它的值) ,vl 从 X 同步到 X’,然后 B 从 X’读取 v1作为 V 的值
图9-4显示了一个异常用例,其中 A 将 v1写入 V,B 读取 V 的值,但是 X 和 X’之间的同步失败,因此 B 读取的值与 V 的最新值不一致,B 仍然读取 v0,而最新更新的值是 v1。
如果要确保 B 总是读取正确的值,则需要确保同步地将更新后的值 v1从 X 复制到 X’。
换句话说,这两个操作-
(1) A 将 X 中 V 的值从 vO 更新为 v1;
(2) V (即 v1)的更新值从 X 复制到 X’-需要在单个事务中。
这样的设置描述在图9-5。这种设置将保证这个分布式事务的原子性,但会影响延迟和可用性。
如果出现如图9-4所示的故障情况,资源将被阻塞,直到网络修复,X 和 X’之间的更新值复制完成。
如果 X 和 X’之间的数据复制过程是异步的,就没有办法知道它发生的确切时间。如果一个人不知道事件确切发生的时间,显然没有办法保证事件是否已经发生,除非他寻求明确的共识或确认。如果需要等待一致同意或确认,则对异步操作的延迟和可用性的影响与同步操作的影响没有太大区别。
因此,分布式系统还是可能发生故障的,数据一致性、系统可用性和分区容忍度之间的权衡需要被理解,需要在其中两个优于第三个的情况下做出选择,因此,第三个是妥协的。
这些选择可以如下:
选项1-可用性受到影响,但是一致性和分区容错性优先于它。
选项2-系统只有很少或没有分区容错性。一致性和可用性是首选。
选项3-一致性受到影响,但是系统总是可用的,并且可以在其部分被分区时工作。
传统的事务性 RDBMS 在横向扩展的情况下选择选项1。
在这种情况下,可用性受到许多因素的影响,包括以下因素:
-
网络延迟
-
通讯瓶颈
-
资源衰竭
-
导致分区的硬件故障
本文正在参加「金石计划 . 瓜分6万现金大奖」