分布式系统的CAP定理
CAP定理|理论
在一个分布式系统中,
- Consistency(数据一致性)
- Availability(服务可用性)
- Partition tolerance(分区容错性)
三者不可兼得,最多只能同时满足二点,没法三者兼顾。
一致性(Consistency)
在分布式系统中的所有数据备份,在同一时刻是否具有相同的值(所有节点持有的是否都是同一份最新的数据)。
比如数据库主库写,从库读,用户完成支付再查询订单状态,主库执行写操作把订单状态改为了已支付,从从库查询订单状态时要是已支付,数据是一致的、同步的。
更新操作执行成功后所有的用户都应该读到最新的数据,即所有数据备份都是最新的数据,这样的系统被认为具有强一致性。
优点: 数据一致,数据不会出错;缺点: 效率低下。
- 强一致性(strong consistency)
任何时刻,所有用户都能读取到最近一次成功更新的数据,所有用户读取的数据都是最新的。
- 单调一致性(monotonic consistency)
任何时刻,用户一旦读取到某个数据在某次更新后的值,就不会再读到比这个值更旧的值,即读取到的数据的版本是单调递增的。
- 会话一致性(session consistency)
在某次会话中,用户一旦读取到某个数据在某次更新后的值,在本次会话中就不会再读取到比这个值更旧的值。
会话一致性是在单调一致性的基础上进一步放松约束,只保证单个用户、单个会话内的单调性,在不同用户或同一用户的不同会话之间则没有保障。
- 最终一致性(eventual consistency)
不能保证用户读取到的是最近一次更新后的数据,但系统可以保证数据最终会达到完全一致的状态,只是所需时间不能保障。
- 弱一致性(weak consistency)
用户无法在确定时间内读到最新的数据。
不满足强一致性,但一般都要使用一些方式(加锁),使数据具有最终一致性。
可用性(Availablity)
负载过大后,系统是否还能响应客户端的读写请求,响应指的是在正常时间内处理完请求。
比如原来qps(每秒访问量)是1000,现在涨到10000,依然能正常访问。
分区容错性(Partition-torlerance)
即高可用性,一个节点崩溃、故障,不会影响到其它节点。
怎么才能做到?增加机器数量,做集群,少数节点挂掉,集群整体依然可用。
集群节点越多,分区容错性越强,但完成这些机器数据同步花费的时间也越多,IO压力大,数据一致性越得不到保证(越差)。
满足CA,不满足p
满足A=>在指定时间内处理完请求,满足C=>完成机器的数据同步,要在指定时间内处理完请求、并完成数据同步,那集群的机器就得少(机器多了同步要花大量时间、时间不够),所以不满足P。
满足CP,不满足A
满足P=>集群、机器多,满足C=>数据同步、要花时间,机器又多、还要等这些机器完成数据同步才处理请求,那完成响应的时间就得不到保证,所以不满足A。
满足AP,不满足C
满足A=>指定时间内完成,满足P=>集群、机器多,机器又多、还要再指定时间内完成这些机器的数据同步,指定时间内数据可能复制不完、同步得不到保证,所以不满足C。
一台机器肯定是不行的,一旦发生什么故障,比如该服务器网络故障,系统就挂了。
一般都要做集群来保证分区容错性(P,高可用),所以往往是在A、C之间取舍。
ZK保证了数据一致性(C),但选举新的leader时集群不能对外提供服务,不满足可用性(A)。
Eureka保证了可用性(A),Eureka是去中心化的,集群每个节点的地位都是一样的,一个Eureka Server挂了,其它的Eureka Server不受影响,依然能对外提供服务,
但每个Erueka Server都需要从其它所有的Eureka Server上同步数据,容易受网络故障影响,网络波动一下数据就不一致了,不满足数据一致性(C)。
选择注册中心时,看项目对A、C中哪一个需求更高:
对C要求高的,比如银行的项目都涉及钱财,优先选择ZK。负载大了大不了用户访问不了,钱财好歹是安全的、账目好歹是对的。
对A要求高的,比如选课系统,高考、四六级查分,电商系统,负载大时依然要可用、扛得住,优先选Eureka。