这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
今天和大家分享分布式的相关理论基础笔记。
什么是分布式
分布式系统是计算机程序的集合,这些程序利用跨多个独立计算节点的计算资源来实现共同的目标。
分布式可以分为:分布式计算,分布式存储,分布式数据库等
常见的分布式系统
分布式存储
- Google File System(
GFS):google 分布式文件系统 - Ceph :统一的分布式存储系统
- Hadoop HDFS :基于 GFS 架构的开源分布式文件调用系统
- Zookeeper :高可用的分布式数据管理与系统协调架构
分布式数据库
- Google Spanner :google 可扩展的,全球分布式的数据库
- TiDB :开源分布式关系型数据库
- HBase :开源Nosql数据库
- MongoDB :文档数据库
分布式计算
- Hadoop :基于 MapReduce 分布式计算架构
- Spark :再 Hadoop 基础之上,使用内存来存储数据
- YARN :分布式资源调度
分布式理论
Cap 理论
CAP 理论往往运用于数据库领域,但同时也适用于分布式存储方面。
- C (Consistence) 一致性,指数据在多个副本之间能够保持严格的一致性。
- A (Availability) 可用性,指系统提供的服务都保证可以一直可用(但不能保证返回最新的数据)。
- P (Network partitioning) 分区容错性,分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障。
根据上面的理论,我们可以预测下面问题的解决方案:
在网络发生分区的情况下,当出现故障节点时我们必须满足可用性和一致性,近似的解法:把故障节点的负载转移给备用节点负责。(故障转移)
BASE 理论
BASE 理论是对 CAP 理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。
- 基本可用(Basically Available): 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
- 软状态(Soft State): 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。MySQL Replication 的异步复制也是一种体现。
- 最终一致性(Eventual Consistency): 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
分布式事务
两阶段提交
提交请求(投票)阶段
- 协调者向所有参与者发送prepare请求与事务内容,询问是否可以准备事务提交,并等待参与者的响应。
- 参与者执行事务中包含的操作,并记录undo日志(用于回滚)和redo日志(用于重放),但不真正提交。
- 参与者向协调者返回事务操作的执行结果,执行成功返回yes,否则返回no。
提交(执行)阶
分为成功与失败两种情况。
若所有参与者都返回yes,说明事务可以提交:
- 协调者向所有参与者发送commit请求。
- 参与者收到commit请求后,将事务真正地提交上去,并释放占用的事务资源,并向协调者返回ack。
- 协调者收到所有参与者的ack消息,事务成功完成。
若有参与者返回no或者超时未返回,说明事务中断,需要回滚:
- 协调者向所有参与者发送rollback请求。
- 参与者收到rollback请求后,根据undo日志回滚到事务执行前的状态,释放占用的事务资源,并向协调者返回ack。
- 协调者收到所有参与者的ack消息,事务回滚完成。
三阶段提交
上述的两阶段提交流程所存在的问题:
- 最严重的风险,如果发起者在第二步 confirm 的过程中出现了异常、或由于网络问题部分执行者没有收到 confirm,那么会出现数据不一致的问题。
- 第一步操作会锁定资源,然而有可能操作不成功,需要释放资源。这种反复的“锁定-释放”降低了并发。
三阶段提交在两阶段提交上的改进就是在之前多了一步:
在锁定资源之前先进行查询,确认是否可提交。 这种写法并没有解决数据可能出现不一致的问题,只是尽量的去优化了这一过程(即提前判断是否可以进行操作,避免了反复的“锁定-释放”的可能。)。
MVCC
这里提到两个锁的概念:
- 悲观锁:操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据
- 乐观锁:不会上锁,只是在更新是判断别人是否修改数据,只有出现冲突的时候放弃操作
上述的描述时一般的数据库储存时的策略,但是 MVCC 提供了另一种思路:为每一个修改保存一个版本,和事物时间戳相关联。这样的作法可以提高并发性能,并且解决脏读的问题。
Quorum NWR 模型
在Quorum NWR算法中,存在三个参数:N、W、R。这里依次进行介绍
副本数 N
参数N为副本数,又被称作复制因子。其含义是一份数据在整个集群中的副本数量。注意其与集群中节点数量并无任何关系
写一致性级别 W
参数W为写一致性级别(Write Consistency Level),其含义为成功完成W个副本更新、写入,才会视为本次写操作成功
读一致性级别 R
参数R为读一致性级别(Read Consistency Level)。类似地,其含义为成功从R个副本读取相应数据,才会视为本次读操作成功
下面就N、W、R参数在不同组合条件下,如何实现强一致性、最终一致性进行介绍:
- 当 「W + R > N」 时,根据**「鸽巢原理」**可知,在进行读操作时R个副本返回的结果中一定包含最新的数据。然后再利用时间戳、版本号等手段即可确定出最新的数据。换言之在满足该条件的参数组合下,可以实现数据的强一致性
- 当 「W + R <= N」 时,无法实现强一致性,其只能保障最终一致性。即系统可能会获取旧数据
事实上当W=N、R=1时,即所谓的WARO(Write All Read One)。就是CAP理论中CP模型的场景。综上所述从实际应用角度出发,Quorum NWR算法有效解决了AP模型下不同业务场景对自定义一致性级别的需求
Reft 协议
Reft 协议是解决分布式问题的很重要的协议之一,也是目前使用最为广泛的分布式协议之一。
角色
Reft 协议包含了如下三种角色,这三种角色在合适的时间会进行角色转换(例如从群众 -> 候选人):
- Leader(领袖):领袖由群众投票选举得出,每次选举,只能选出一名领袖;
- Candidate(候选人):当没有领袖时,某些群众可以成为候选人,然后去竞争领袖的位置;
- Follower(群众):进行投票和接收领袖信息。
选举
Reft 协议包含这样一个重要的过程:选举。选举会在新的任期或者群众的 ”选举定时器“ 超时时发生。进行选举过程中,还有几个重要的概念:
Leader Election(领导人选举):简称选举,就是从候选人中选出领袖;
Term(任期):它其实是个单独递增的连续数字,每一次任期就会重新发起一次领导人选举;
Election Timeout(选举超时):就是一个超时时间,当群众超时未收到领袖的心跳时,会重新进行选举。
领袖心跳 :领袖B需要时刻向群众发起心跳,当群众A和C收到领袖B的心跳后,群众A和C的“超时时间”会重置,然后重新计数,依次反复。当选举人的心跳出现异常时,比如领袖挂掉了,那么A和C就会发生超时从而转换成候选人并开始选举。
角色转换
群众 -> 候选人:新任期开始选举或者当“选举超时”时
候选人 -> 候选人:当“选举超时”,或者开始新的“任期”
候选人 -> 领袖:获取大多数投票时
候选人 -> 群众:其它节点成为领袖,或者开始新的“任期”
领袖 -> 群众:发现自己的任期ID比其它节点分任期ID小时,会自动放弃领袖位置
数据同步
上面的基础概念理清后,我们来看Reft协议是如何实现分布式储存的:
当 Client 发起数据更新请求,请求会先到领袖节点C,节点C会更新日志数据,然后通知群众节点也更新日志,当群众节点更新日志成功后,会返回成功通知给领袖C,至此完成了“提交”操作;当领袖C收到通知后,会更新本地数据,并通知群众也更新本地数据,同时会返回成功通知给Client,至此完成了“应用”操作,如果后续Client又有新的数据更新操作,会重复上述流程。(提交-应用操作对应上面提到的两阶段提交)