架构师训练营第一期 - week6
题目
回答
1. 请简述 CAP 原理
定义
CAP 指 C(Consistency)一致性,A(Availability)可用性,P(Partition Tolerance)分区容错性。
一致性:每次读取的数据都应该是最近写入的数据或者返回一个错误,而不应该过期的数据。
可用性:每次请求都应该得到响应,而不是返回一个错误或者失去响应,不过这个响应不需要保证数据是最近写入的。
分区耐受性:即时因为网络原因,部分服务器节点之间消息丢失或者延迟了,系统依然是可以操作的。
分布式系统只能满足三项中的两项而不可能满足全部三项。理解 CAP 理论的最简单方式是想象两个节点分处分区两侧。
允许至少一个节点更新状态会导致数据不一致,即丧失了 C 性质。
如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了 A 性质。
除非两个节点可以互相通信,才能既保证 C 又保证 A,这又会导致丧失 P 性质。
证明
假设有两台服务器,一台放着应用 A 和数据库 V,一台放着应用 B 和数据库 V,他们之间的网络可以互通,也就相当于分布式系统的两个部分。
现在有两个网络 N1 和 N2,每个网络中都存在一个服务用于从 db 获取数据,初始状态下,db 中存储的数据都是 V0。
在单机情况下,忽略网络1和网络2的延时。在网络 N1 通过服务 A 更新 V0 到 V1,更新成功后发送消息 M 使 N2 db 中的 V0 变为 V1,此时我们通过服务 B 获取数据时,获取到 V1。此时为CA,没有分区
但是一旦发生了网络分区 (分区容错性强制拥有),此时我们通过服务 A 更新数据到 V1 后,由于延时,V1 值不能实时同步到 N2 网络中去,此时我们调用服务 B 去请求数据的时候,我们必须从 C 和 A 选一个,
如果选择 C,我们需要等到数据同步到 N2,但是从服务 B 获取数据肯定是失败了,失去了 A。
如果选择 A,那么从 B 我们获取到的数据不是最新的,失去了 C。
CAP的取舍
CAP 三个特性只能满足其中两个,那么取舍的策略就共有三种:
CA without P
如果不要求 P(不允许分区),则 C(强一致性)和 A(可用性)是可以保证的。但放弃 P 的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,退化成一个单机系统,这是违背分布式系统设计的初衷的。
CP without A
如果不要求 A(可用),相当于每个请求都需要在服务器之间保持强一致,而 P(分区)会导致同步时间无限延长 (也就是等待数据同步完才能正常访问服务),一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。设计成 CP 的系统其实不少,使用场景有:
- zoomkeeper 服务注册与发现中心集群
在集群中,包含一个 Leader 节点,其余全部为 Follower 节点。Leader 节点负责读和写操作,Follower 节点只负责读操作。当客户端向集群发出写请求时,写请求会发送到 Leader 节点,Leader 写操作完成后,采用广播的形式,向其余 Follower 节点复制数据,Follower 节点也写成功,返回给客户端成功。流程如图:
如图,在服务 A 向 zoomkeeper 集群注册时,写请求会被转发到 Leader 节点 (zoomkeeper1),此时,Leader 节点写入成功后,会通知 zoomkeeper2 和 zoomkeeper3 节点进行复制,并且复制成功了才会向服务 A 返回注册成功的状态。此后,服务 B 通过集合获取服务 A 的地址,无论从哪个节点都能获取服务 A 的服务地址。
- 分布式事务两阶段提交
第一阶段,事务协调器要求每个涉及到事务的数据库预提交 (pre commit) 此操作,并反映是否可以提交。第二阶段,事务协调器要求每个数据库提交数据。如果有任何一个数据库否决此次提交,那么所有数据库操作的数据都会回滚。
AP without C
要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。使用场景有:
Redis集群与MySQL 集群
数据复制都是采用的异步复制,所以都属于 AP 类型,在集群中获取数据时,会存在数据不一致的情况。
eureka 服务注册与发现中心集群
在集群中,新增一个 eureka 实例时,集群中的实例是相互复制其注册的服务实例数据。示例如下:
如图,在服务 B 向 Eureka2 注册成功后,此时,Eureka2 还没向 Eureka3 复制成功就挂掉了,此时,在 Eureka 的服务注册与发现中心集群中造成了数据不一致。当服务 A 通过服务注册于发现中心集群通过 Eureka3 来拿服务 B 的地址时,就无法拿到。
总结
分布式系统中,一般P是必须保证的,在AC之间选择。但是对于传统的项目就可能有所不同,拿银行的转账系统来说,涉及到金钱的对于数据一致性不能做出一丝的让步,C 必须保证,可以在 A 和 P 之间做取舍,出现网络故障的话,宁可停止服务。
没有最好的策略,好的系统应该是根据业务场景来进行架构设计的,只有适合的才是最好的。
2. 针对 Doris 案例,请用 UML 时序图描述 Doris 临时失效的处理过程
包括判断系统进入临时失效状态,临时失效中的读写过程,失效恢复过程
判断系统进入临时失效状态
应用服务访问失效节点失败,应用服务会发起重试
应用服务器失败3次后向管理中心请求仲裁
管理中心向失效节点发送心跳检测
心跳失效,管理中心反馈仲裁,判定存储服务进入临时失效状态
临时失效中的读写过程
临时失效中读数据只从正常节点读取,写入数据写入正常节点,同时将写入操作写入日志节点
临时失效的恢复过程
失效恢复期间,读、写、数据恢复会同步发生,但与正常态有所不同:
数据恢复:数据将会从日志节点迁移到恢复节点中
读操作:依旧只读取正常节点的数据
写操作:同时写入正常节点和故障恢复节点
对于恢复节点,写入数据冲突按照时间戳新的数据覆盖旧的
当临时节点的数据全部迁移成功后,失效态结束,所有存储服务按正常态运行,日志节点的数据之后会被删除。
评论