CAP、BASE跟后面要看的分布式事务有直接的关系,但是这两个分布式的理论对我们研究分布式系统里面的一些技术和方案都是作为基础的知识需要掌握的
这个CAP这个东西啊,也是个在研究分布式相关的问题中,比较经典的这么一个理论,大家在学习下面的知识之前,最好是先有相关知识的一个积累,这样下面学习起来才会比较轻松一些
CAP,就是Consistency、Availability、Partition Tolerence的简称,简单来说,就是一致性、可用性、分区容忍性,所以这个CAP理论讲的就是这么个东西,但是这里的话呢,其实大家觉得很虚,虚的不行,简直是虚头巴脑啊
所以网上很多类似的什么CAP理论的文章和博客,都是这么讲解的,大家看了就觉得心里凉凉的,不知道是啥玩意儿
(1)一致性
先说说C,就是一致性吧,这个其实很好理解,就是说一个分布式系统中,一旦你做了一个数据的修改,那么这个操作成功的时候,就必须是分布式系统的各个节点都是一样的,
能说,客户端发起一个数据修改的请求,然后服务器告诉他成功了,结果去查的时候,从某个节点上查询数据,发现这个数据不对啊,这样的话就成了数据不一致了,就是分布式系统的各个节点上的数据是不一样的,就是不一致
这个所谓一致性还分成几种:
啥叫强一致性呢,就是说上面讲的那种就是强一致性;弱一致性呢,就是你更新个数据,鬼知道能不能让各个节点都更新成功;最终一致性,就是可能更新过后,一段时间内,数据不一致,最后过了一段时间成功了
最终一致性,应该是分布式系统中非常常见的这么一个东西,redis主从同步,你可以做成主从异步同步的,主节点同步数据到从节点上去的时候,异步,最终一致性的体现。
你的一个客户端往redis主节点里面写入了一条数据,在一段时间内,你客户端如果从redis从节点去查询数据,此时可能是查不到的,但是redis主从机制给你保证的是,过了一段时间之后,你再查,一定是可以从redis从节点里查到的
(2)可用性
这个A,就是可用性,其实也很好理解,就是你的分布式系统必须是可用的啊,说句不好听的,要是一会儿访问你是成功,一会儿访问你失败,那失败的时候就是不可用,有不可用的情况存在,就导致可用性降低了
什么叫做可用?客户端往分布式系统的各个节点发送请求,都是可以获取到响应的,要不是可以写入成功,要不是可以查询成功;什么叫做不可用呢?客户端往分布式系统中的各个节点发送请求的时候,获取不到响应结果,这个时候,系统就是不可用了,写入失败,人家不让你写入,不接受你的请求
可用性分成好多级别,比如99%,99.9%,99.99%,99.999%
99%,一年中只能有80小时左右是可以允许访问失败的
99.9%,一年中大概有8小时左右是可以访问失败
99.99%,一年中有大概不到1小时是可以访问失败的
99.999%,一年中有大概不到5分钟是可以访问失败的
99.9999%,一年中只能有大概不到1分钟可以访问失败
那一般来说,就我个人观察,很多行业大部分的系统,其实99%可用性都没到,或者可能大概就在99%是一个很正常的水平,每年总得故障几次。能做到99.9%的系统就算是比较牛的了,也算很不错了,毕竟一年内就几个小时不可用
一般做到99.99%,也就是所谓的4个9,那就是比较高的水平了。而至于说99.999%,五个9,那是行业内的顶尖水平
(3)分区容忍性
分区,partition,network partition,网络分区 => 分布式系统之间的网络环境出了故障,分布式系统的各个节点之间现在已经无法进行通信了
分区容忍性,你的分布式系统可以容忍网络分区的故障,出现上面说的那种网络分区的故障之后,分布式系统的各个节点之间无法进行通信,无所谓,整套分布式系统各个节点,各自为战,该干嘛干嘛,只不过互相之间无法通信而已
分布式系统还是在运转着,你分别给各个节点发送请求,人家还是可以给你一些响应结果的,这个就是实现了分区容忍性
这玩意儿搞的稀奇古怪的,啥东西啊,其实说白了,就是一个分布式的系统,如果遇到了网络分区的故障,也就是说,分布式系统互相之间无法联通了,这个时候咋整呢,有点儿恶心啊,这里要求的是,遇到网络分区故障,也类似于传说中的脑裂吧,然后系统还是可以正常对外提供服务的
如果不具备分区容忍性,那会怎么样呢?那就是说一旦网络故障,整套系统崩溃,你哪怕给各个节点发送消息,全部失败,清一色失败,整套系统甚至会宕机,不再运转了
(4)CAP => CP or AP
不可能CAP三者兼得的,CAP理论里面,最最重要的一点,就是说,不可能一个分布式系统同时兼备一致性、可用性、分区容忍性,要么几句是CP(一致性 + 分区容忍性),要么就是AP(可用性 + 分区容忍性)
基于这套理论,redis、mongodb、hbase什么什么的分布式系统,都是参照着CAP理论来设计的,有些系统是CP,有些系统是AP
(4)CP
一般来说,CAP要么同时满足AP,要么同时满足CP,不可能同时满足CAP的,啥意思呢
如果实现CP的时候,为什么就无法同时满足AP了?为什么有了一致性,就不能有可用性了?CAP里面,为什么要们是CP,要么是AP?为什么一定要有P?分区容忍性,分布式系统,如果一旦出现了一些网络分区的故障之后,保证整套系统继续运转是非常重要的一点,所以很多分布式系统es,都设计了防止脑裂的机制
P是一定要有,CP,AP,CA(不存在的)
CP,为什么就没有A了呢?
假设,出现了网络分区的故障,但是因为有P,所以分布式系统继续运转,但是此时分布式系统的节点之间无法进行通信,也就无法同步数据了
此时客户端要来查询数据,也就是那个key1的数据了,此时系统实际上是处于一个不一致的状态,因为各个节点之间的数据是不一样的,如果客户端来查询key1这条数据,你要是要保证CP的话,就得返回一个特殊的结果(异常)给客户端
任何一个节点此时不接收任何查询的请求,返回一个异常(系统当前处于不一致的状态,无法查询),这样的话呢,客户端是看不到不一致的数据的
此时对客户端而言,要么查到的是一致性的数据,要么如果数据不一致什么都查不到,不让你看到不一致的数据,这就保证了CAP里的C,一致性,分布式系统本身处于不一致的时候,让你看不到不一致的数据,就保证了一致性,保证了CP
但是此时的话,就牺牲掉了A,可用性,因为此时不让你看到不一致的数据,所以你发送请求过来是返回异常的,请求失败了,此时分布式系统就暂时处于不可用的状态下,也就是保证了CP,就没有了A
弄个分布式系统给大家演示一下,就俩节点,假设现在发生了网络分区故障,好了,那么P起码要保证吧,就是网络分区的时候,系统还是要正常可以运行的,所以P先保证了,对吧,然后呢,因为网络分区,导致俩节点互相不能通信了
现在呢,你写入一条数据到其中一个节点,好了,结果这个节点没法同步数据到其他的节点上去啊,咋整呢,尴尬啊尴尬,俩节点上数据不一致了
所以这个时候,如果你要满足C,也就是一致性,你觉得应该怎么办,你要是继续让所有人访问两个节点,那数据100%不一致,一会儿数据这样,一会儿数据那样,这个时候,你就只能牺牲掉A了
也就是说,在这种情况下,你的系统直接对外不再提供服务,人家查询直接返回异常,不让查到不一致的数据,不就可以保证一致性了,呵呵,但是你就牺牲了可用性了,因为这个时候你的系统是不可用的
经典的就是一些分布式存储,比如说zookeeper、mongodb、hbase等等,跟他们都是CP的,也就是说数据100%一致,但是有可能有些时候你请求是失败的,不让你请求到不一致的数据,这就是CP
如果要保证CP的话,C,保证说你在任何情况下写入一条数据,接着从任何一个节点去查都可以看到一致的数据,不可能让你一会儿看到旧数据,一会儿看到的是新数据,这样就保证了一致性
有些特殊的情况下,确实数据就是没法同步,没法一致性,此时可能就得牺牲A了,可能短暂的情况下,你发送请求过去人家返回异常给你,此时就是短暂不可用的,让你过段时间在重试查询
(5)AP
如果网络故障,数据没同步,数据处于不一致的状态下,要保证A,可用性,你两个节点都要允许任何客户端来查询,都可以查到,这样的话呢,整个系统就处于可用的状态下,但是此时就牺牲掉了C
一会儿可以查到key1的数据,一会儿从另外一个节点去查又查不到了,这就是对客户端而言,看到了不一致的数据
在各种分布式系统里面,CAP不可能同时兼得,指的主要是什么呢,就是发生网络故障的时候,可能一些数据没有同步一致性,此时要么就是CP,要么就是AP
那如果要保证AP呢,也就是可用性必须保证,人家过来查必须给人查,那就牺牲掉一致性咯,随便查,要怎么查怎么查,但是查到的数据不一致,那我不管了,反正就这么回事儿了,哈哈哈。。。起码我可用性保证了,一致性就没了
对于12306、电商系统,这种业务类系统,一般都是AP,也就是说,你可能看到的商品库存或者火车票的库存,是错的,有可能是旧的啊,那么数据很可能看到的都是不一致的,但是呢,你买东西或者买票的时候,一定会检查库存,就可以了
但是保证了可用性就ok,任何时候都要响应结果,不能动不动就失败
12306买票,AP,C其实是没保证的。很多人同时在订票,每次订票之后这个车票的库存就会扣减,但是车票库存扣减之后,可能不能及时的被你的12306网站展示出来,可能你查询的车票的库存,是从另外一个库里去查的,最新的库存数据还没同步过来,此时数据是不一致的
所以你看到的是不一致的数据,C,但是AP,可用性是保证的,时时刻刻都让你可以看到数据,可以买票,可以查询,但是呢可能你看到的车票还剩5张,但是你发起订票的时候,人家一检查最新的库存,判断已经是0张了,就不让你买了呗
(6)BASE理论
所谓的BASE,Basicly Available、Soft State、Eventual Consistency,也就是基本可用、软状态、最终一致性
BASE希望的是,CAP里面基本都可以同时实现,但是不要求同时全部100%完美的实现,CAP三者同时基本实现,BASE,基本可用、最终一致性
此时要保证基本可用性,应该怎么办呢?两个节点都可以查询的,但是这个时候你会发现说有的节点可以返回数据,有的节点无法返回数据,会看到不一致的状态,这个不一致的状态,就是指的是BASE中的S,soft state,软状态
基本可用,降级,正常情况下,是查询可以负载均衡到各个节点去查的,也就是可以多节点抗高并发查询,但是此时如果你要降级的话,可以降级为,所有客户端强制查询主节点,这样看到的数据暂时而言都是一样的,都是从主节点去查
但是因为客户端访问量太大了,同时用一个主节点来支撑很坑,扛不住,怎么办呢,主节点做限流降级,也就是说如果流量太大了,直接返回一个空,让你稍后再来查询
如果你这样子来降级了,保证的就是所谓的基本可用,降级的措施在里面了,跟正常的可用是不一样的,比正常的可用要差一些,但是还是基本可以用的
最终一致性,一旦故障或者延迟解决了,数据过了一段时间最终一定是可以同步到其他节点的,数据最终一定是可以处于一致性的
这个基本可用的意思,就是说可以适当进行降级,比如说某些系统是可以进行降级的,在故障的时候,直接引导到降级的一些功能里去,举个例子吧,本来商品详情页可以是个极度华丽的页面,但是如果降级的话,那么就变成一个比较简陋的页面,里面包含少量数据
软状态意思就是说,可以存在中间的数据状态,就是比如多个节点在同步数据,在一段时间内,可能每个节点数据不一致,正在同步过程中,这个就是软状态
最终一致性,就是说,虽然存在软状态,但是最终还是会变成一致的
所以说,CAP和BASE是俩理论,是俩基础理论,你在设计分布式系统的话,可以用CAP中的CP或者AP,也可以采用BASE理论,有一些不一样,也有一些关系