CAP和BASE算是耳熟能详的名字了吧,本篇文章中,想结合自己已有的亿点点实践经历,谈谈自身的理解。
CAP的英文名和中文名如下:
个人觉得在不同的场景下,关于一致性的理解是各种各样的。在数据操作方面的一致性,可以理解为数据的变化情况和单线程的场景下的变化情况应该保持一致。如:网上电影售票时,不能出现一张票卖给了多个人,即出现漏减的情况。
在事务方面的一致性(即ACID中的C)可以理解为“目标”上的一致性,譬如,一次A转账给B100元的过程,目标是A的账户扣100,B的账户增100,这个“目标”要么达成,要么不达成,不能只完成一半。(为了防止扁桃体同学抬杠,这里强调不是在事务过程中)是不是觉得很像原子性,当然了,原子性只是保证事务一致性的手段之一。
在数据存储方面(这里指数据分布在服务器集群中),一致性可以指数据在多台服务器上分布协调,如一致性哈希算法就可以解决这个问题,也可以多个指同步数据的副本的数据一致,例如我们的elasticsearch,在客户端发起数据更新请求后,可以让所有副本分片同步更新后才让协调节点返回成功。
尽管不同场景下的一致性理解稍微有些不同,但它却有着与之对应的模型。这里只说了比较烂大街的强一致性、弱一致性、最终一致性。
对了,这里还要再扯一下,一致性实现的算法很多,像很多人张口就来什么Paxos、Raft什么的。其实,这些个算法从英文翻译过来时,叫做共识算法比较好理解一些。这些个算法,大都假设存在拜占庭问题,在此背景下,让分布式下的多个节点的投票可以达成共识。
而我们这里通常所说的一致性,大都指这么个情况,为了保证容错性,我们通常会用多个副本来同步主节点的数据,如何让数据在副本和主节点上保持一致性的问题。
强一致性(线性一致性)
CAP中的C就是强一致性,按百科的描述就是,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)。在实际运用中,关于强一致性的实现一般都很难真正的实现。这也不难解释,有些中间件会在主节点选举时,容易造成脑裂问题。而强一致性的情况下,是不应该出现这个问题的。
弱一致性
分布式下,弱一致性指产生数据后,不需要所有节点就立刻都看到,但不同不同的节点看到这些新数据时需要按照它们处理时的顺序。譬如A、B、C三个节点,A上产生新数据,依次同步到B、C,不能说同步给B时,还没到C,C就能看到了。
最终一致性
这个下面分析base时说。
可用性指在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求能力。(对数据更新具备高可用性)。
可用性,范围说小一点,譬如只单节点可用性,我们可以考虑是否可以启动多个服务,挂载不同的磁盘,进行伪负载均衡,防止某个盘挂了,服务就不可用了。当访问的数量量上来后,这是我们就需要考虑集群的方案了。这时,用户的访问量由多台集群进行负载,考虑到访问量还是可能超过集群限制,我们又得增加一些限流或者熔断措施。考虑到某个服务挂了之后,程序需要自动切换到另一台服务,此时就引入服务注册与发现中心。
分区容错性可以理解为当存在网络分区时(另个子系统之间的网络不可达),系统仍可继续运行的能力。在分区恢复后,保证分区容限的分布式系统还可以从分区正常恢复。
看了一些文章,目前分区容错性也可以理解为系统对节点动态加入和离开的处理能力,因为节点的加入和离开可以认为是集群内部的网络分区。
BASE比CAP放宽了条件,放弃了CAP理论的C(强一致性),强调最终一致性。基本可用来表明可用性。
BASE:全称:
基本可用是指分布式系统在出现不可预知的故障的时候,允许系损失部分可用性。最常见的,双11淘宝在遇到大流量的购买操作后,此时,用户继续购买时,会跳转到一个引导页。从而保证其他服务的正常运行。
软状态表示即使没有输入,系统的状态也可能随时间变化。这个软状态又指中间状态,数据同步过程可以存在一定的延迟。譬如我们Kafka中的ISR伸缩,它表示follower副本同步leader节点需要的延时差,这个是允许存在的。
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后(软状态),最终能够达到一个一致的状态。
个人认为,BASE是CAP的一个拓展,结合实际运用场景,放宽了条件。其中,CAP的C指待的是强一致性,而BASE的E指的是最终一致性。CAP的A只的是可用性,而BASE的B强调的是基本可用。
另外,CAP的精髓在于一个分布式系统不可能同时满足这三点,一致性、可用性、分区容错性。如果强调CA(一致性和可用区),需要牺牲P(分区容错性)
基于CA的设计不能满足P,由于C追求强一致性,一般就没有了多个数据副本了,只有一个的数据副本满足了强一致的需求,最常见于单节点系统,此时遇到不可预知的错误,服务器它完犊子了,哦吼,系统不能访问了,不具备分区容错性。
基于CP的设计(zookeeper,话说zookeeper的一致性应该是弱一致性,不能归类为CAP中的C才对,非要归类,也应该是Eventually consistent),牺牲了A(可用性)。在分区出现故障后,不断通过重试来恢复,这个期间的可用性无法满足。
基于AP的设计(Eureka),牺牲了C(一致性)。分区(P)越来越多,可以理解为备胎越来越多,为了不给他们凑在一起打麻将的机会,我们需要牺牲掉C(一致性),即信息在多个分区间的同步具有延时性的特点。