正确理解CAP定理

简介

定义

原文: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集群、redis哨兵不属于讨论对象

  • web集群只是资源复制分配在不同的节点上,然而节点间没有互连、也没有数据共享(sessionid、memory cache)。
  • memcached集群数据存储是通过客户端实现哈希一致性,但是集群节点间不互连的,也没有数据共享。
  • redis哨兵是为了Redis提供了高可用性,进行监控、通知、故障转移等,但没有数据读写操作。

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

一致性(Consistency)

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

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

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

简单描述下,这里没说明是所有节点必须在同一时间数据一致,而关注点在客户端,假如有个场景,您在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).

扫描二维码关注公众号,回复: 1626209 查看本文章

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

关键字: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-牺牲分区容错性

作为分布式系统,我认为CAP的讨论是建立在P确立前提下。假如我们牺牲了P这个时候因为网络故障发生了分区导致节点不可用,这个时候请求响应了error,与可用性的定义相冲突了。因为分区总会发生,因此对于分布式系统而言分区容错性是必要的。

PC-牺牲可用性

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

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

PA-牺牲一致性

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

猜你喜欢

转载自www.cnblogs.com/skychen1218/p/9194065.html