分布式基础知识 - CAP权衡【转载】

本文转自之前的阿里内网,本来只是摘抄给自己看的,现在想把这部分内容体系的整理下分享给团队成员,原文链接找不到了,没有盗取知识成果的意思

一、背景介绍


分布式系统是指由若干独立部署的机器组合对外统一的服务的系统,一个分布式系统具有硬件独立、软件统一的特征。分布式系统的出现主要应对的是单机计算能力和存储能力的不足。

目前我们接触的很多系统都是分布式的,例如:

  • 分布式事务:2PC,3PC,TCC,TXC等
  • 分布式选举算法:zab,raft,paxos以及各种变种
  • 分布式存储和数据库:Hbase,Cassandra,CouchDb,TiDB等
  • 分布式消息系统:kafka,rocketmq,metaq等
  • 分布式监控和跟踪:Dapper,zabbix,CAT,eagleeye等
  • 分布式缓存:redis,tair,memcache等

这些方案其实都是为了解决具体问题在高性能和高可用而做出的不同取舍。之所以要一定做出这种权衡,而不能全部解决就是基于的分布式理论基础——CAP原理。

二、CAP简介


1. CAP原理


CAP 理论是分布式系统中对数据的管理而形成一套理论知识,是设计分布式系统所必须考虑的架构问题,在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性 (Consistency)、可用性 (Availability)、分区容错性 (Partition Tolerance)三者中的两个,另外一个必须被牺牲。

2. CAP的适用范围


定义中强调了两点:

  • 相互连接
  • 共享数据

分布式系统并不一定会互联和共享数据。例如 Memcache 的集群,相互之间就没有连接和共享数据,因此 Memcache 集群这类分布式系统就不属于 CAP 理论探讨的范畴。而常见的 MySQL 主从集群就是互联和进行数据复制的,因此是 CAP 理论探讨的对象。

3. CAP原理说明

(1)一致性

CAP 中的 C 是指可线性化,可线性化的定义是如下:如果B操作在成功完成A操作之后,那么整个系统对B操作来说必须表现为A操作已经完成了或者更新的状态。可线性化是一种十分强的一致性,要求系统写入什么,读出来的也会是什么。

(2)可用性

具备CAP可用性的系统要求满足以下条件:每一个请求如果被一个工作中的节点收到,那一定要返回非错误的结果

通过上述定义可以得出以下几个重要结论:

  • 首先每一个请求都需要得到结果,如果由于分区导致部分请求不能执行,那么不能称之为CAP可用
  • 系统中的每个节点都能得到结果,如果一部分节点由于分区而不能工作,那么也不能称之为CAP可用
  • 可用性指的是完全的可用,也即是100%可用,返回的结果一定是非错误的结果

(3)分区容错性


分区容错性是指当网络分区发生时,依然会提供满足一致性或者可用性的服务。

在分布式系统中由于网络延迟以及故障是一定会发生的,分区容错性是必须要满足的。


三、如何根据CAP设计分布式系统

那么讲了这么多概念,当我们设计一个分布式系统的时候,如何在把 CAP 理论作为指导呢?在这一节会以注册中心为例,介绍如何设计一个分布式系统。

1. 分析数据特性


在很多 CAP 理论的定义和解释中,用的都用系统、节点这类系统级的概念,这就给很多人造成了很大的误导,认为我们在进行架构设计时,整个系统要么选择 CP,要么选择 AP。在 “请不要再称数据库是CP或者AP” 一文有很重要的一句话:CAP系统的模型是一个只能读写单个数据的寄存器。

通过这句话可以得到一个重要的结论:CAP 系统关注的是单一数据,而不是整个系统,一个分布式系统中可能存在多种数据, 依据不同的数据特性会采用不同的策略。以12306为例,余票数量是要求很强的一致性,超卖是不能接受的;相比之下用户的邮箱等基本信息更新不及时则没那么重要。

【注册中心能接受不一致吗】

注册中心保存的是服务的注册信息,也就是每个服务提供者对应 IP 和端口号。那么这些数据如果出现不一致,会出现什么情况呢?请看下面的例子。

 

上图中服务 svcB 有10个节点,调用者 svcA 调用者通过注册中心查询两次服务,得到了不同的数据,第一次是{ ip1,ip2,ip3...,ip9 },第二次是{ ip2,ip3,....ip10 }。结果是 ip1 和 ip10 相对其它 8 个节点{ip2…ip9}请求流量小了一点。因此作为注册中心,出现不一致的情况是可以接受的。

如果选择了一致性呢?

再看看在网络分区的情况下,如果选择 Zookeeper 作为注册中心时,为了保证 C 而放弃 A 会产生什么影响。

 

当机房 3 出现网络分区时,整体 ZooKeeper 服务是可用的,但是节点 ZK5 因为联系不上 leader 是不可写的。也就导致机房 3 的应用服务 svcB 是不可以新部署,重新启动,扩容或者缩容的。但是站在网络和服务调用的角度看,机房 3 的 svcA 虽然无法调用机房 1 和机房 2 的 svcB, 但是与机房 3 的 svcB 之间的网络是联通的,所以更加合理的方案是在分区情况下依然能调用本机房的 svcB。

通过上面的阐述可以得出结论,注册中心的可用性比数据的一致性更加重要,所以整体设计更应该偏向 AP,而非 CP,只要数据不一致在可接受范围。这也是阿里自研注册中心 ConfigServer 而不使用 Zookeeper 的原因之一。

2. 分区检测


什么是分区?大家的第一反应是网络发生断开,但是如果网络断开0.1毫秒之后又重连上了,那应该认为发生网络分区了吗?

其实网络分区的本质是延迟,CAP理论是基于没有延迟的假设,也就是在网络连通的情况下数据能够瞬间复制到各个节点。但是现实情况中延迟总是存在的,当数据复制到其他节点之前系统就处于了不一致的状态,为了保持一致性此时我们是取消操作还是等待呢,很明显我们是需要等待的,因为这个延迟是必然存在的,只要系统在合理时间内达到状态一致。但是由于网络拥堵,延迟变大,我们可能就要考虑取消操作了。因此分区检测的本质是延迟,网络是否连接只是表象。

延迟多少算进入分区,是系统设计时第一个要考虑的因素,如果时间太短则会导致频繁进入分区模式,而时间太长又会导致系统内数据的严重不一致。

分区的检测有很多种方式,例如

  • 定时发送心跳。这也是很多系统都会采用的方式,既可以是客户端主动发送心跳,也可以是服务店定期检查,还可以两种结合。
  • 请求失败或者超时。这种情况是指正常处理请求的时候发生的,心跳可以认为是主动发现分区,那么这种方式就可以认为是被动检测分区。

3. 限制操作


当检测到延迟(分区)的时候,就需要系统做出决定限制某些操作。选择限制什么操作,实际上就是在 CP 和 AP 之间作权衡。

CAP 的本质就是分区时限制某些操作。

(1)Zookeeper 的选择


为了提高读性能,Zookeeper 默认读取的是节点的本地的数据副本,而不是收集 quorum 或者访问 leader,这就导致默认配置下可能读取到过期的数据,ZooKeeper 默认不满足CAP的一致性定义。可线性化的读操作在ZooKeeper中是支持的,需要在读操作之前发一个 sync() 命令,这时候才满足 CP 的定义,但也会导致数据读取缓慢。

再讨论 Zookeeper 的可用性,Zookeeper 要求一个写操作要求获得半数以上投票才能处理。如果发生网络分区,那么拥有多数节点的分区还可以继续处理读写,而拥有少部分节点的分区则不能正常工作。所以 ZooKeeper 在网络分区的情况下不满足 CAP 的可用性。但是在 ZooKeeper 3.4.0 加入了一个只读的模式。在这个模式下,少部分节点的分区还可以继续处理读操作,不需要 quorum,这个读操作是满足CAP可用性的。

所以 ZooKeeper 默认设置既不是 "CP" 也不是 "AP",只是"P"。但是可以通过用 sync() 命令来让它成为 CP。并且在正确的设置下,读操作(不包括写)其实是CAP可用的。通过 ZooKeeper 的例子可以发现,分布式系统设计并不是简单的二选一关系,而是需要在实际场景中作出合适取舍。

(2)ConfigServer 的选择

 

正常情况下,ConfigServer 部署在 et2 和 eu13 机房,两两互写达到多副本数据的一致性。当 et2 和 eu13 出现网络分区时,eu2 和 eu13断裂成小集群,ConfigServer 的 self check 机制会清除另一个机房的 provider,确保 et2和 eu13 机房内部的 RPC 调用不受影响。在网络分区期间 ConfigServer 集群一样可以读写,可用性不受影响。

4. 分区恢复


如果选择了可用性,在分区时允许写操作,那么就会导致系统产生不一致状态当。这不表示牺牲系统的一致性,当网络分区恢复时,需要做的就是将数据恢复最终的一致状态。

以 Zookeeper 为例,当分区结束时,处于少数区域的节点会重新和 leader 建立连接,将 leader 会自身的数据同步到 follower 节点上,来恢复系统内数据的一致性。

四、总结


本文主要介绍分布式系统设计的 CAP 原理的,在给出明确定义的同时纠正了一些常见的误解。在CAP原理的指导下,设计一个分布式系统首先要明确数据的特征,针对不同的数据特征采取不同的策略。当分区发生时限制选择限制某些操作(就是 C 和 A 之间的权衡),当分区结束之后作出补偿。

分布式系统设计没有通用法则,CAP理论只是给出了设计思路,在系统设计时需要作出合理的权衡。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【江湖】三津

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值