CAP理论是在设计分布式系统的过程中,处理数据一致性问题时必须考虑的理论,一个分布式系统最多只能同时满足一致性(Consistence)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。
2000年7月Eric Brewer教授仅仅提出来的是一个猜想,2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP理论,并且而一个分布式系统最多只能满足CAP中的2项。之后,CAP理论正式成为分布式计算领域的公认定理
比如Redis他就是 AP 特性(所以它才能搞可用)、 Zookeeper就是CP特性
所有节点在同一时间的看到的数据相同、即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,不能存在中间状态。
分布式环境中,一致性是指多个副本之间能否保持一致的特性。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处理一致的状态。

.png)
一致性又可分为强一致性和弱一致性&最终一致性
如果的确能像上面描述的那样时刻保证客户端看到的数据都是一致的,那么称之为强一致性、比如12306就是强一致性的、用户下单购票之后,必须要所有节点同步扣除票余额才算订票成功,避免超票的情况
允许中间状态、只要经过一段时间后,通过定时或者其他方式、数据最终是一致性的,则称为最终一致性(比如我们生活中看到的评论这些就可以使用最终一致性)
允许存在部门数据不一致
服务器一直是可用的、不会出现错误、即使我数据不一致,我也会返回老的数据给你看,但是不能保证数据是否最新的
从两个维度去考虑
有限时间内
比如有一个用户下单了一个操作、必须在指定的时间内给用户响应结果、强调1s法则,不能为了保证分布式事务的一致性,需要10分钟才能处理完,10分钟才给用户响应结果、在互联网应用显然是不能接受的。
返回正常结果
客户请求了服务器、在处理用户请求的时候、服务器发生了异常,不能直接丢给用户一个 Exception、或者超时时间太长了。

客户端请求服务器的时候、服务器需要做很多处理耗时长、如果要保证A可用性的话、就可以使用异步的方式、提前给客户响应结果
即使系统的某个分区遇到严重的故障,系统能继续提供服务。仍然需要能够保证对外提供满足一致性和可用性的服务、除非是整个网络环境都发生了故障
网络分区,是指分布式系统中,不同的节点分布在不同的子网络(机房/异地网络)中,由于一些特殊的原因导致这些子网络之间出现网络不连通的状态,但各个子网络的内部网络是正常的,从而导致整个系统的网络环境被切分成了若干孤立的区域。组成一个分布式系统的每个节点的加入与退出都可以看做是一个特殊的网络分区。

如果发生失败,就要在A和C之间做出选择、要么停止系统进行错误恢复,要么继续服务但是降低一致性,所以我们说只能保证AP或CP
放弃分区容错性的话,则放弃了分布式,放弃了系统的可扩展性、相当于就是一个单体应用了
放弃可用性的话、架构模式就是CP 、在遇到网络分区或者其他故障的时候、为了保证数据的一致性、则需要等待一定的时间或者是直接无法使用

放弃一致性(指的是强一致性)、架构模式就是AP、无法保证系统数据的实时一致性、在数据达到最终一致性时,有个时间窗口,在时间窗口内,数据是不一致的。
对于分布式系统来说,P是不能放弃的,因此架构师通常是在可用性和一致性之间权衡。

目前大多数大型系统应用都是分布式部署的、分布式场景下中的数据一致性问题一直是一个比较重要的话题。
基于CAP理论、很多系统在设计之初就要对着三者做出取舍、任何一个分布式系统都无法同时满足一致性(Consistency) 、可用性(Availability)、分区容错性(Partition tolerance) 、最多只能同时满足两项。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性
为什么分布式系统中无法同时保证一致性和可用性?
首先一个前提,对于分布式系统而言,分区容错性是一个最基本的要求,因此基本上我们在设计分布式系统的时候只能从一致(Consistency)和可用性(Awailability)之间进行取舍
CAP和ACID中的A和C有什么区别?
A的区别


C的区别


ACID里的一致性指的是事务执行前后,数据库完整性,而CAP的一致性,指的是分布式节点的数据的一致性。背景不同,无从可比
BASE是CAP理论的延伸、对于一致性(Consistency)我们采用的方案是保证最终一致性。
eBay的架构师Dan Pritchett源于对大规模分布式系统的实践总结,在ACM上发表文章提出BASE理论,BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(StrongConsistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。
在分布式系统出现故障的时候,允许损失部分可用性,支持分区失败,即保证核心可用。
接受一段时间的状态不同步,及中间状态,而改中间状态不影响系统整体可用性。这里的中间状态就是CAP理论中的数据不一致性、允许系统在不同节点的数据副本之间进行数据同步的过程存在延时
系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态、其本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性
主要是对AP的补充。牺牲数据的强一致性,来保证数据的可用性,虽然存在中间装填,但数据最终一致、允许数据在一段时间内是不一致的,但最终达到一致状态
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我正在尝试复制此GETcurl请求:curl-D--XGET-H"Authorization:BasicdGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="-H"Content-Type:application/json"http://staging.example.com/api/v1/campaigns在Ruby中,通过电子邮件+apikey生成身份验证:auth="Basic"+Base64::encode64("test@example.com:4c3186288ae23fd9661c
我正在向我的Controller发送一个base64图像并按原样保存它。现在我需要显示该图像。这是我要显示的内容,但未显示图像:"/>为了编码,我使用了这个java脚本函数encodeURIComponent();我的编码图像格式:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/........ 最佳答案 你不需要解码base64应该可以 关于ruby-on-rails-在rails中显示base64编码的图像,我们在StackOve
我见过几个模型定义了一个静态方法self.base_attributes{:object=>[]}end还有一些模型定义了静态方法self.attributes@@attributes={}end属性和基本属性到底有什么区别? 最佳答案 在您的示例中,您无需了解更多代码,self.attributes方法使用类变量(@@attributes),这意味着您可以添加在运行时给它更多的属性。因为您的base_attributes是硬编码的。我怀疑你看到的是这样的东西:base_attributes.merge(attributes)这可能
我正在为我未构建的应用程序编写Controller测试,因此这绝对是一个学习过程。这是我第一次遇到直接继承自AbstractController::Base的Controller。显然,它的行为与其他Controller不同。其格式大致为:classSchwadGenericController我尝试了正常测试,这是我目前要让任何事情发生的地方。require'rails_helper'describeSchwadGenericControllerdo#before(:each)do#SchwadGenericController.skip_authorize_resource#end
我正在尝试检索以base64编码格式接收的图像的内容类型和文件名。这是使用base64编码图像执行POST请求的代码require'net/http'require"rubygems"require'active_support'url=URI.parse('http://localhost:3000/')image=ActiveSupport::Base64.encode64(open("public/images/rails.png").to_a.join)post_params={'image'=>image}Net::HTTP.post_form(url,post_params
我遇到了sinatracondition方法,但对它的工作原理感到困惑。我有一段代码:defauthuserconditiondoredirect'/login'unlessuser_logged_in?endend它检查用户是否登录了某些路由,示例路由:get'/',:auth=>:userdoerb:indexenduser_logged_in?方法定义在项目lib目录下的帮助文件中:defuser_logged_in?ifsession[:user]@user=session[:user]return@userendreturnnilend所以,问题是:conditionbloc
在Ruby中,我们可以在单例方法中使用super来调用对应父类(superclass)的单例方法,如下面的代码所示。classBasedefself.class_methodputs"Baseclassmethod"endendclassDerived但是,我似乎不太明白Derived.class_method中对super的调用如何到达Base.class_method。我假设class_method是在他们的元类上定义的,这是否意味着他们的元类具有父/子关系?(我无法通过实验完全证实这一点)更新:我问这个问题是因为我记得在某处看到基类和派生类的元类之间存在某种关系(但我找不到它不再
我正在就Ruby语言和环境向.NET(C#)开发团队进行一系列演讲。我把它当作一个机会来强调Ruby相对于C#的优势。首先,我想在进入环境之前专注于语言本身(RoR与ASPMVC等)。你会介绍Ruby语言的哪些特性? 最佳答案 我刚才在一个.NET用户组做了一个关于IronRuby的演讲,遇到了类似的问题。我关注的事情是:鸭子打字。没有什么比ListstringList=newList()更愚蠢的了;表达力强,语法简洁。简单的事情,比如省略括号、数组和散列文字等(结合鸭子类型,你会得到string_list=[]这显然更好)。所有的