本文是对http://book.mixu.net/distsys/ebook.html这篇文章中关于CAP理论的总结。
CAP:
Consistency: all nodes see the same data at the same time.
对于同一个数据的多个副本,在任何时候副本数据是一致的。-a single copy
Availability: node failures do not prevent survivors from continuing to operate.
当节点发生故障,比如进程崩溃时,不会影响其他存活节点继续执行服务。
Partition tolerance: the system continues to operate despite(尽管) message loss due to
network and/or node failure.
为什么说CA是不可行的?
A CA system does not distinguish between node failures and network failures, and hence must stop accepting writes everywhere to avoid introducing divergence (multiple copies). It cannot tell whether a remote node is down, or whether just the network connection is down: so the only safe thing is to stop accepting writes。
因为不知道是网络故障还是进程故障,为了不对数据引入分歧,最好的做法就是拒绝服务。但这就与可用性发生了冲突。
此外在不能支持分区容错行的系统中无法达到一致性。所以要想达到一致性,必须支持分区容错性。考虑下面的例子。
在一个跨进程的服务中A发送消息给B执行服务,此时会出现几种情况,
1:B接收到A的消息并成功执行了服务,但是在返回成功消息给A时出现了网络通信故障或者在发送返回消息之前B进程崩溃了,A不会收到B的确认消息。
2:B进程没有收到A的消息,更不会给A返回消息了。
3:B接收到了A的消息,但随后进程崩溃没有给A返回消息。
由于A没有收到B的确认消息,那么A就没法确定B进程到底成功执行了服务没有,如果不能确定B进程服务是否成功执行了服务,无论做哪种处理都会对B进程服务涉及的数据的一致性引入分歧。
CP系统的实现(保持大多数节点分区可用,使少数节点分区不可用)
Strong consistency guarantees require us to give up availability during a partition. This is because one cannot prevent divergence between two replicas that cannot communicate with each other while continuing to accept writes on both sides of the partition.
在CP系统中为了保证数据的一致性,当网络出现分区的时候会造成不同分区的数据的不一致(因为分区的节点没办法就某个操作达成一致)。此时我们必须使得节点数较少的分区中所有的节点都不可用来保证强一致性。
AP系统的实现
强一致性的定义是:对于同一个数据的多个副本,在任何时候副本数据是一致的。如果我们对这个定义弱化一下,
产生弱一致性的定义:对于同一个数据的多个副本,我们最终能保证数据是一致的。
如果某些场景下数据的实时一致性并不重要,那么我们可以通过对系统一致性和可用性的权衡,来保证系统的分区容错性、可用性和弱一致性。但是有些场景下数据必须是强一致性的,比如银行的系统。那么其就只有舍弃可用性了。
实现强一致性的坏处:
Strong consistency / single-copy consistency requires that nodes communicate and agree on every operation. This results in high latency during normal operation. If you can live with a consistency model other than the classic one, a consistency model
that allows replicas to lag(延迟) or to diverge(分歧), then you can reduce latency during normal.
operation and maintain availability in the presence of partitions.
实现强一致性需要所有的节点对某个操作达成一致(比如二阶段提交协议)这需要大量的进程间通信,这会导致系统操作的延迟。
此外,强一致性是业务程序员与系统之间的约定,即通过业务程序员的代码实现来实现业务数据强一致性。其并不是一个系统保证。所以所谓的强一致性,只有在业务代码正确且对业务做了强一致性处理时才可能保证强一致性(这取决于程序员的素质),这意味着强一致性保证似乎并没有什么保证。
实现弱一致性的坏处和好处:
坏处:多个数据副本出现不一致的情况下,整合数据是一个技术挑战,当然这也是一个业务风险。如果需要面临的技术挑战和业务风险是可控的,影响较小的那么可以考虑实现弱一致性。
好处:减少了操作的延迟,可以提高系统的可用性。
强一致性和弱一致性的区别。
强一致性模型保证了更新的明显顺序和可见性,相当于一个非复制系统。系统维护单一的数据源。例如通过锁、乐观锁机制进行并发控制实现的事务保证了强一致性。而弱一致性不提供这样的保证。
另外这里提及另外一个不可能理论FLP:
FLP:
there does not exist a (deterministic) algorithm for the consensus problem in an asynchronous system subject to failures, even if messages can never be lost, at most one process may fail, and it can only fail by crashing (stopping executing).
在异步通信场景,即使只有一个进程崩溃,也没有任何算法能保证非失败进程达到一致性!