什么是CAP定理?
2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。之后,CAP理论正式成为分布式计算领域的公认定理。
CAP定理的含义是:一个分布式系统,不可能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三个基本需求,最多只能同时满足其中的两个。
CAP定理的三个指标
Consistency
一致性,指的是写操作成功后,所有节点在同一时间读到的的数据完全一致,都是最新的。
这里的一致性说的是强一致性。
想要了解更多关于一致性类型或分布式一致性问题可以看这篇文章:分布式一致性问题。
如何实现一致性(强一致性)?
- 数据写入主库后要同步到从库;
- 同步期间需要将从数据库锁定,同步完成后释放锁,防止在数据未同步成功之前,向从数据库请求到旧的数据。
Availability
这里有个点需要注意以下,CAP中的C和事务的ACID中的C都是指一致性(Consistency),但是CAP中的A指的是可用性(Availability) ,与**事务的ACID中的A(Atomicity)**不是一个东西。
可用性是指任何请求都能得到正常响应,且不会出现响应超时或响应出错,即服务一直都是可用的。
如何实现可用性?
- 数据写入主数据库后要同步到从数据库;
- 由于要保证从数据库的可用性,写入过程中不可以对从数据库的资源加锁;
- 即使新数据还没同步过来,从数据库也要即时响应请求,即使返回的是旧数据,但不能响应超时。
Partition tolerance
分区容错性是指遇到某节点或网络分区故障的时候,其他正常的节点还可以正常提供服务。
分区容错性和扩展性紧密相关。通常是一个分布式系统的基本要求。
如何实现分区容错性?
- 尽量使用异步代替同步,例如,使用异步的方式将主数据库数据同步到从数据库,这样可以有效的实现松耦合;
- 添加节点,这样一个从节点挂了,还有其他从节点可以提供服务。
CAP之间应该如何权衡?
既然CAP三个指标最多只能同时满足两个,那么应该舍弃哪一个呢,下面分情况讨论一下:
CA without P
这种情况在分布式系统中是基本上不存在的。在分布式的环境下,网络分区是必然的事实,一旦舍弃了分区容错性,那分布式系统的存在也就没有意义了。
对分布式系统来说,P是一个基本要求。
CP without A
舍弃了A(可用性)也就意味着,一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,即容许系统停机或长时间无响应,等所有数据全部一致了再继续提供服务。
在不要求强可用性的分布式系统中是可以这样设计的。
比较典型的就是很多分布式数据库,入Redis、HBase,还有分布式协调组件Zookeeper也是优先保证CP的。在发生极端情况的时候,牺牲系统的可用性,优先保证强一致性。
其实可以理解,数据的一致性是他们的基本要求,若是连数据的一致性也不能保证,还要他分布式存储有何用?
AP without C
要高可用并允许分区,则需放弃一致性。一旦网络问题发生,节点之间可能会失去联系。为了保证高可用,需要在用户访问时可以马上得到返回,则每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致。
这里说的舍弃一致性其实也不准确,而是舍弃了强一致性,退而求其次保证最终一致性,因为一个系统连数据都是不准确的,那么系统存在的价值也就没有多少了。
这种设计的案例是非常多的,比如淘宝、京东之类的商城,12306购票等。
适合的才是最好的
到底哪一种设计是最好的,并没有定论,只能说适合的才是最好的。
如果系统中涉及到金钱这种绝不能让步的场景,那么一定要保证C(一致性),宁可服务停机也一定要保证数据一致。
对于其他大多数场景,通常会保证高可用和分区容错,舍弃强一致性,退而求其次选择最终一致性保证数据安全。