该文的阅读感想
CAP理论断言,最多只能满足数据一致性、可用性、分区容忍性这三要素中的两个。
通过显式处理分区情景,系统设计师可以做到优化数据一致性和可用性,进而取得三者的平衡。我自己对这句话的理解是这样的,假设现在存在两个节点N1和N2,所有更新操作都会互相通知,显然可以满足数据一致性C。当两者不能互相连接的时候,有三种情况:1. 两者继续服务,更新数据,此时数据必定不一致,就是放弃了C来换去A,同时维护P;2.N1和N2都不服务,放弃可用性来取得C和P。3. 只有N1服务,此时数据一致性得到部分保留,可用性得到部分保留,同时维护了P。我觉得第三种就是这种所谓的权衡。
作者指出,三选二这样的语句本身是不严谨的。实际上,只有在分区存在的前提下呈现完美的数据一致性和可用性这种很少见的情况是CAP理论所不允许出现的。因此在实际设计中有着很多的变通方案和灵活度。
CAP在大多数时候允许完美的C和A,那在P出现的时候,准备一些策略去处理其影响即可,包括:
ACID和BASE分处一致性-可用性分布图谱的两极
数据库的传统设计思路,注重一致性,写入数据库教材的经典原则。这也是事务transaction的基本性质
CAP理论的经典解释是忽略网络延迟的,但实际中延迟和分区密切相关。在操作的间隙,系统需要作出决策:
依靠多次尝试通信来达成一致性,比如Paxos算法或者两阶段事务提交,仅仅是推迟了决策时间。无限期地尝试下去,本身就是选择一致性牺牲可用性的表现。
从延迟的角度抓住了设计的核心问题:分区两侧是否在无通信的情况下继续操作?
从这个实用的观察角度导出两条推论:
对于可用性和一致性的作用范围的误解比较严重。
离线模式正在变得越来越重要,比如HTML5的客户端持久化存储特性。这些离线系统在C和A中会更倾向于A,此时就不得不在长时间处于分区状态后进行恢复。
“一致性的作用范围”其实反映了这样一种观念,即在一定的边界内状态是一直的,但超出了边界就无从谈起。比如在一个主分区内可以保证完备的一致性和可用性,而在分区外服务是不可用的。
由于基本操作是原子的,因此分区检测一定发生在两个事务之间,然后在分区结束后执行分区恢复来恢复一致性。
当系统进入分区模式,有两种可行的策略。其一是限制部分操作,因此会削弱可用性;其二是额外记录一些有利于后面分区恢复的操作信息。系统可以通过持续尝试恢复通信来察觉分区何时结束。
决定限制哪些操作,主要取决于系统需要维持哪几项不变性约束。
对分区两侧跟踪操作历史的最佳方式是使用版本向量,版本向量可以反映操作间的因果依赖关系。向量的元素是(节点, 逻辑时间)数值对,分别对应一个更新了对象的节点和它最后更新的时间。对于同一对象的两个给定的版本 A 和 B,当所有结点的版本向量一致有 A 的时间大于或等于 B 的时间,且至少有一个节点的版本向量有 A 的时间较大,则 A 新于 B。
到了某个时刻,通信恢复,分区结束。 分区恢复过程中,设计师必须解决两个问题:
通常情况,矫正当前状态最简单的解决方法是回退到分区开始时的状态,以特定方式推进分区两侧的一系列操作,并在过程中一直保持一致的状态。 这样总是会有存在不能自动合并的冲突的情况,比如版本控制系统CVS,如git,就会有需要手动合并分支的时候。 相反,有些系统用了限制操作的办法来保证冲突总能合并。因此,虽然总的来说冲突问题不可解,但现实中设计师可以选择在分区期间限制使用部分操作,以便系统在恢复的时候能够自动合并状态。如果要实施这种策略,推迟有风险的操作是相对简单的实现方式。 还有一种办法是让操作可以交换顺序,这种办法最接近于形成一种解决自动状态合并问题的通用框架。但是好像挺复杂的,作者的说法是实现起来没那么容易
一般系统在分区恢复期间检查违反情况,修复工作也必须在这段时间内完成。
恢复外在错误通常要求知道一些有关外在输出的历史信息。以“喝醉酒打电话”为例,一位老兄不记得自己昨晚喝高了的时候打过几个电话,虽然他第二天白天恢复了正常状态,但通话日志上的记录都还在,其中有些通话很可能是错误的。拨出的电话就是这位老兄的状态(喝高了)的外在影响。而由于这位老兄不记得打过什么电话,也就很难补偿其中可能造成的麻烦。
曾经有人正式研究过将补偿性事务作为处理长寿命事务(long-lived transactions)的一种手段 21,22。长时间运行的事务会面临另一种形态的分区决策:是长时间持有锁来保证一致性比较好呢?还是及早释放锁向其他事务暴露未提交的数据,提高并发能力比较好呢?比如在单笔事务中更新所有的员工记录就是一个典型例子。按照一般的方式串行化这笔事务,将导致所有的记录都被锁定,阻止并发。而补偿性事务采取另一种方式,它将大事务拆成多个分别提交的子事务。如果要中止大事务,系统必须发起一笔新的、起纠正作用的事务,逐一撤销所有已经提交的子事务,这笔新事务就是所谓的补偿性事务。
经验太少,没太看明白