大白话讲解分布式里面的cap原则
什么叫做cap
Cap分别指可用性,分区容错性,一致性
分区容错性
如下图中,G1 和 G2 是两台跨区的服务器。G1 向 G2 发送一条消息,G2 可能无法收到。系统设计的时候,必须考虑到这种情况。一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。所以在cap原则里面,分区容错性是必须要有的
一致性
一致性的意思是,写操作之后的读操作,必须返回该修改后的值。举例来说,某条记录是 v0,然后客户端向 G1 发起一个写操作,将其改为 v1,但是此时注意G2里面的记录还是v0,而不是v1,就像下面这样
然后当用户向G1获取记录的时候,返回就是v1,就像下面这样,这样是没有问题的
但是如果用户向G2服务器获取记录的时候,此时记录还是v0,这就有问题了,因为用户在两个服务获取的记录数据不同,这就是不一致性,怎么解决不一致性呢:我们可以在我们可以在 G1 写操作时,锁定 G2 的读操作和写操作。只有G1完成写操作并且把修改数据同步到G2之后,G2服务器才能重新开放读写操作
为什么可用性和一致性无法都使用
如下图,如果保证 G2 的一致性,那么 G1 必须在写操作时,锁定 G2 的读操作和写操作。只有G1和G2把修改后的数据同步后,才能让G2服务开放读写操作。但是在G2服务器锁定期间,G2 服务器是不能进行读写操作的,所以此时可用性是不可能实现的。
然后如果保证 G2 的可用性,那么势必不能锁定 G2的读写操作,所以刺死一致性不成立。
综上所述,G2 无法同时做到一致性和可用性。系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。
可用性
可用性意思是只要收到用户的请求,服务器就必须给出回应。
为什么可用性和一致性无法都使用
如下图,如果保证 G2 的一致性,那么 G1 必须在写操作时,锁定 G2 的读操作和写操作。只有G1和G2把修改后的数据同步后,才能让G2服务开放读写操作。但是在G2服务器锁定期间,G2 服务器是不能进行读写操作的,所以此时可用性是不可能实现的。
然后如果保证 G2 的可用性,那么势必不能锁定 G2的读写操作,所以刺死一致性不成立。
综上所述,G2 无法同时做到一致性和可用性。系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。
我们在开发过程中cap原则,我们应该怎么选择呢
我们一般都是保证一致性和分区容错性,而舍弃可用性,因为你想啊,一致性对比可用性,还是一致性重要吧,特别是涉及到重要的数据,就比如钱,商品数量,商品价格,如果这些数据你保证可用性,那么就会出现不同时间的访问可能造成数据的不(因为每一次访问的时候可能会访问到不同的服务器),这就大发了,支付宝每一次访问的钱金额不同,你说要命不要命
但是也有使用可用性,而放弃一致性的,举例来说,发布一张网页到 CDN,多个服务器有这张网页的副本。后来发现一个错误,需要更新网页,这时只能每个服务器都更新一遍。一般来说,网页的更新不是特别强调一致性。短时期内,一些用户拿到老版本,另一些用户拿到新版本,问题不会特别大。当然,所有人最终都会看到新版本。所以,这个场合就是可用性高于一致性。
所以cap原则里面到底怎么选,看情况而定
在开发中我们经常遇到zookeeper是使用分区容错性和一致性,而springcloud里面的ribbon的重试机制是保证可用性和分区容错性
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
聊聊新的Go语言错误处理方案
今天早些时候,golang/x/exp中默默的更新了一个名曰xerrors的包,这个包和同样处于golang/x/exp下的另一个名叫errors的包名字十分相似,就连介绍也都一致: Package errors implements functions to manipulate errors. This package implements the Go 2 draft designs for error inspection and printing 从目前的情况来看,基本上错误的处理形式基本已经定型,处理方式则是类似于之前的另一个github.com/pkg/errors包,但是具体细节不尽相同。 如何处理error? 在之前介绍文章中提到过github.com/pkg/errors包的设计思路,那么在Go团队的实现中,这种思
- 下一篇
这道面试必问的JVM面试题70%的Java程序员会做错
前言聊聊JVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别。JVM可以说和我们是老朋友了,但是在工作中的应用场景也许不如那些框架,但是在关键时候还是得靠它去搞定问题,俗话说得好,知己知彼,方能百战不殆,JVM作为前往高级工程师的一道坎,从这篇文章开始,我们会去逐步的分析,讲解,攻克这座大山。有关Java虚拟机类加载机制相关的文章一搜一大把,就也不必再赘述一遍了。在这里捞出一道code题要各位大佬来把玩把玩,如果你一眼就看出了端倪,那么恭喜你,你可以下山了: 问题:请问这段程序的输出是什么?一般对于这类问题,小伙伴们脑海中肯定浮现出这样的知识点Java中赋值顺序:父类的静态变量赋值自身的静态变量赋值父类成员变量赋值和父类块赋值父类构造函数赋值自身成员变量赋值和自身块赋值自身构造函数赋值按照这个理论输出是什么呢?答案输出:1 4,这样正确嚒?肯定不正确啦,这里不是说上面的规则不正确,而是说不能简单的套用这个规则。正确的答案是: 有没有答对呢?这里主要的点之一:实例初始化不一定要在类初...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS关闭SELinux安全模块
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Linux系统CentOS6、CentOS7手动修改IP地址