CAP

发现自己貌似理解了CAP这么久,其实不太准确。重新理理思路记录一下。

首先是CAP的确切概念。以cap-faq的定义为例:

Availability: will a request made to the data store always eventually complete?
Consistency: will all executions of reads and writes seen by all nodes be atomic or linearizably consistent?
Partition tolerance: the network is allowed to drop any messages.

有点咬文嚼字,再看foundationdb的定义

Availability: Reads and writes always succeed.
Consistency: A read sees all previously completed writes.
Partition tolerance: Guaranteed properties are maintained even when network failures prevent some machines from communicating with others.

CAP理论中的Availability与我们服务承诺的SLA中的可用性不是一回事,可以说CAP中的A是指“强可用性”,部分可用或写不可用读可用在CAP的概念里都不能称为可用,但通常SLA保证的可用性,只要不是完全挂掉,都算是可用。

一致性在CAP里同样指强一致,也即linearizably consistent或linearizability,如cap-faq中的例子,set(10),set(4),get()->10是最终一致,而非强一致。

网络划分好理解。

平时说CAP三选二,其实CA系统现实中并不存在,因为没有绝对可靠的网络,网络划分一定会出现,当出现P无法满足时,C和A必须二选一,也就是要么是CP系统,要么是AP系统。单主架构必定是CP系统(当然可能CP都不是),如MongoDB,多主架构或All-Peers(其实也是多主)架构一定是AP系统,如Cassandra。

所以有时我们争论说“该场景是个CAP场景,我们满足不了”,很可能是一种错误,因为业务方很可能可以接受一般意义上的“可用性”,也可能事实上可以接受最终一致。

CAP放松一些限制,就可以形成一个很实用的系统,如我们的Redis集群,简单的将强一致放松为最终一致,就可以实现网络划分的情况下读可用。虽然此时严格上讲,这个系统AP和CP都算不上。更多情况下,一个分布式系统会融合CP和AP,CP的部分负责维护一些关键的共享数据,比如用ZooKeeper维护集群状态,AP部分保证系统的可用性。