zoukankan      html  css  js  c++  java
  • 正确理解CAP定理

    前言

      CAP的理解我也看了很多书籍,也看了不少同行的博文,基本每个人的理解都不一样,而布鲁尔教授得定义又太过的简单,没有具体描述和场景案例分析。因此自己参考部分资料梳理了一篇与大家互相分享一下。

      标题写了正确理解,或许某些点不是百分百正确或者有歧义,但是希望与各位分享讨论后达到最终正确

    简介

      CAP定理,又被称作布鲁尔定理(Brewer's theorem),是埃里克·布鲁尔教授在2000 年提出的一个猜想,它指出对于一个分布式系统来说,不可能同时满足以下三点:

    • Consistency(一致性): where all nodes see the same data at the same time.(所有节点在同一时间具有相同的数据)
    • Availability(可用性): which guarantees that every request receives a response about whether it succeeded or failed.(保证每个请求不管成功或者失败都有响应)
    • Partition tolerance(分隔容忍): where the system continues to operate even if any one part of the system is lost or fails.(系统中任意信息的丢失或失败不会影响系统的继续运作)

      很多书籍与文章引用Robert Greiner在2014年8月写的一篇博文 http://robertgreiner.com/2014/08/cap-theorem-revisited/。相比与看着布鲁尔教授一脸懵逼的定义,Robert Greiner的更加容易理解。

    定义

    原文:In a distributed system (a collection of interconnected nodes that share data.), you can only have two out of the following three guarantees across a write/read pair: Consistency, Availability, and Partition Tolerance - one of them must be sacrificed.

    翻译:在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。

    关键字:interconnected nodes(互连节点)、share data(共享数据)、a write/read pair(读/写)

      从上面一段话,有几个,也就是说我们聊CAP定理的时候,是在具有数据读写、数据共享和节点互连的前提下,对上面三者选其二,也是建议我们不要花费时间与精力同时满足三者。

    举例说明,web集群、memcached集群不属于讨论对象

    • web集群只是资源复制分配在不同的节点上,然而节点间没有互连、也没有数据共享(sessionid、memory cache)。
    • memcached集群数据存储是通过客户端实现哈希一致性,但是集群节点间不互连的,也没有数据共享。

    总得来说,CAP定理讨论的并不是分布式系统所有的功能。

    一致性(Consistency)

    原文:A read is guaranteed to return the most recent write for a given client.

    翻译:对某个指定的客户端来说,读操作保证能够返回最新的写操作结果

    关键字:a given client(指定的客户端)。

      这里的一致性与我们平常了解ACID的一致性有点偏差,ACID的一致性关注的是数据库的数据完整性。

       上面定义没说明是所有节点必须在同一时间数据一致,而关注点在客户端,假如有个场景,您在ATM(客户端)往某张银行卡存500元后,立刻在ATM发起查询余额的时候会显示加了500元后的余额,随后我们也能把这500元取出来。查询余额读操作可以是写后立刻读的主库,也或者写后某个时间段过后(中途无写)读从库。

    可用性(Availability)

    原文:A non-failing node will return a reasonable response within a reasonable amount of time (no error or timeout).

    翻译:非故障节点将在合理的时间内返回合理的响应(不是错误或超时)。

    关键字:non-failing node(非故障节点)、reasonable response(合理的响应)

      这里的可用性和我们平常所理解的高可用性有点偏差,高可用性指系统无中断的执行其功能的能力。

      已故障的节点就不具有可用性了,因为请求结果要么error要么 timeout。合理的响应没有说明是成功还是失败,但是响应应该具有是否成功的精确描述。例如我们读取sql server集群的某从库,同步需要时间,读取出来可能不是最新的数据,但却是合理的响应。

    分区容错性(Partition tolerance)

    原文:The system will continue to function when network partitions occur.

    翻译:当网络分区发生时,系统将继续正常运作

    关键字:continue to function(继续正常运作)

      假如做了一个redis的一主两从的集群,某天某个从节点因为网络故障变成不可用,但是另外的一主一从仍然能正常运作,那么我们认为它具有分区容错性。

    CA-牺牲分区容错性

      作为分布式系统,分区必然总会发生(2年1次50分钟还是1年3次共10分钟?),因此认为CAP的讨论是大部分建立在P确立前提下。假设我们牺牲了P这个时候因为网络故障发生了分区导致节点不可用,这个时候请求响应了error、timeout,与可用性的定义相冲突了。

      但是,我们又假如分区大部分时间是不存在的,这时对单节点的读写,那么就无需作出C、A的取舍。但是上面说分区总会发生这不互相矛盾么,还是取舍。假如1年时间内99.99%时间是正常的,不可用时间为0.01%(52.56分钟)不可用,若这个时间属于业务接受范围,或者只在某个地区(华南、华北、华中?)有影响,那么CA也是可以选择的。

    PC-牺牲可用性

      最典型的案例是RDBMS集群与Redis集群,这两种都是利用主从复制实现读写分离的方案。假如两者都是建立一主多从的集群,在主节点写入数据,为了保证随后的读操作获取最新数据(一致性),这个读操作仍会请求主节点(读写分离的复杂点在从库同步不及时导致业务的异常,为了保证业务的正常性写后的读会请求主库),某个从节点挂了但是只要主节点和其他从节点仍然正常运作,就满足分区容错性。但是哪天主节点因为网络故障导致写操作的error或者timeout,那么这个系统就不可用了(牺牲可用性)。

    这个时候可以引入其他功能和机制完成,例如Redis哨兵模式、故障转移功能。

    PA-牺牲一致性

      最典型的案例是Cassanda集群和Riak集群,这种类型的分布式数据库,可以任意节点写入,任意节点读取,当作为集群出现,无论写入哪个节点,都将会把该节点的数据同步到其他节点上,因为这种同步方式,读取数据时只要访问一个节点就足够了(喜欢任意访问也不拦着你),但是因为其他节点数据同步原因,数据可能并不是最新的(牺牲一致性)。如果当前节点因为网络异常导致分区变得不可用(无论读写),可以转移访问节点(可用性)。

    另外这里说的牺牲一致性,并不代表放弃一致性,而PA选择的是最终一致性(系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态)

    总结

      上面涉及“牺牲”字眼,并不代表非此即彼的选择,可以根据子系统、模块之间的设计上进行混搭使用(例如PA和PC、CA和PC)。

      本文对CAP定理做了一个简单的梳理描述,参考了部分书籍和文章加上自己的理解希望可以跟大家做个分享,如果有不同建议和看法包括文章内描述错误,请在下方评论指出,我将及时作出修改。

  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/skychen1218/p/9198551.html
Copyright © 2011-2022 走看看