这是我参与「第五届青训营 」伴学笔记创作活动的第8天
前言
本文讲述一些分布式的知识,如:分布式事务、共识协议等。本文主要以科普为主,之后将会深入对分布式进行学习。
1.分布式
1.定义
分布式系统是计算机程序的集合,这些程序利用跨多个独立计算节点的计算资源来实现共同的目标。可以分为分布式计算、分布式存储、分布式数据库等。
- 优势:去中心化、低成本、弹性、资源共享、可靠性高
- 挑战:节点故障、不可靠的网络、异构的机器和硬件环境、安全
2.使用原因
- 数据爆炸,追求储存和计算的大规模运用
- 成本低,构建在廉价的服务器上
因此,采用分布式框架和成熟的分布式系统来实现。
3.常见分布式系统
2.系统模型
1.故障模型
这里分为六大类:
- Byzantine failure:节点可以任意篡改发送给其他节点的数据,大部分分布式不解决该故障
- Authentication detectable byzantine failure(ADB):Byzantine failure的特例;节点可以篡改数据,但不能伪造其他节点的数据
- Performance failure:节点未在特定时间段内收到数据,即时间太早或太晚
- Omission failure:节点收到数据的时间无限晚,即收不到数据
- Crash failure:在omission failure的基础上,增加了节点停止响应的假设,也即持续性地omission failure,宕机
- Fail-stop failure:在Crash failure的基础上增加了错误可检测的假设
从上而下的故障解决难度降低,主要考虑了正确性、时间和状态三要素,下图是它们之间的关系:
下图是常见故障对应的故障类型:
2.拜占庭将军问题
该问题是用来解决共识问题的,开始是探索两个将军保持通信同步的方法,后续上升到三个将军等。该方法能保证同步的安全性,并得出结论:理论上永远达不到共识
普遍规律:当有3m+1个将军,其中m个“叛徒”时,可以增加m轮协商,最终达成一致。
Q1:为什么TCP要三次握手?
可以阻止重复历史连接的初始化;可以同步双方的初始序列号;可以避免资源浪费
Q2:挥手过程中,若FIN报文丢失,会发生什么?
- 客户端to服务端:客户端超时重传,超过tcp_orphan_retries直接CLOSE
- 服务端to客户端:服务端超时重传,达到了重传最大次数,于是再等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到客户端的第四次挥手(ACK报文),那么服务端就会断开连接。
3.共识与一致性
- 最终一致性:读写期间存在不一致,写完后读的一致
- 线性一致性:即强一致性,读写后会同步消息到其他线程,同步过程会有时延,系统可用性受损。
4.时间和事件顺序
Lamport逻辑时钟:采用逻辑时钟,可以对整个系统中的事件进行全序排序
3.理论基础
1.CAP理论
- C (Consistence):一致性,指数据在多个副本之间能够保持一致的特性(严格的一致性)。
- A (Availability):可用性,指系统提供的服务必须一直处于可用的状态,每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据。
- P (Network partitioning):分区容错性,分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障。
CAP理论往往运用于数据库领域,同样可以适用于分布式存储方向 上述三者可以相互结合,但不能三者结合即100%,如下图:
- CA:放弃分区容错性,加强一致性和可用性,其实就是传统的单机数据库的选择
- AP:放弃一致性(强一致性) ,追求分区容错性和可用性,例如一些注重用户体验的系统
- CP:放弃可用性,追求一致性和分区容错性,例如与钱财安全相关的系统
在网络发生分区的情况下,须在可用性和一致性之间做出选择。近似解决办法:把故障节点的负载转移给备用节点负责,如下图:
2.ACID理论
事务是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全都不执行。
- 特性:
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
具体介绍如下:
- 原子性(A)。原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
- 一致性(C)。一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
- 隔离性(I)。隔离性是当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离
- 持久性(D)。持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
3.BASE理论
- 演变:对CAP中一致性和可用性权衡的结果,其来源于对大型互联网分布式实践的总结,是基于CAP定理逐步演化而来的。
- 核心思想:Basically Available(基本可用):假设系统,出现了不可预知的故障,但还是能用,相比较正常的系统而言:响应时间上的损失,或功能上的损失
- Soft state(软状态):允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。
- Eventually consistent (最终一致性) :数据最终一定能够达到一致的状态
其与之前提及的理论的关系如下图:
4.分布式事务
1.二阶段提交
为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种演算法。
三个假设:
- 引入协调者(Coordinator)和参与者(Participants) ,互相进行网络通信
- 所有节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上
- 所有节点不会永久性损坏,即使损坏后仍然可以恢复
主要分为两个阶段:prepare阶段和commit阶段
回滚:在Prepare阶段,如果某个事务参与者反馈失败消息,说明该节点的本地事务执行不成功,必须回滚。
- 问题:
- 性能:两阶段提交需要多次节点间的网络通信,耗时过大,资源需要进行锁定,徒增资源等待时间。
- 协调者单点故障问题:如果事务协调者节点宕机,需要另起新的协调者,否则参与者处于中间状态无法完成事务。
- 网络分区带来的数据不一致:一部分参与者收到了Commit消息,另一部分参与者没收到Commit消息,会导致了节点之间数据不一致。
2.三阶段提交
将prepare阶段拆为CanCommit阶段和PreCommit阶段
因此,主要分为三个阶段:CanCommit阶段、PreCommit阶段和Commit阶段
过程如下图:
解决的问题:单点故障问题和阻塞问题
3.MVCC
- 悲观锁:操作数据时直接把数据锁住,其他人不能修改数据,直到操作完成后才会释放锁
- 乐观锁:不会上锁,只是在执行更新时判断别人是否修改数据,只有冲突时才放弃操作
MVCC是一种并发控制的方法,维持一个数据的多个版本使读写操作没有冲突。 MVCC为每个修改保存一个版本,和事务的时间戳相关联。 可以提高并发性能,解决脏读的问题。
时间戳实现方法:
- TrueTime API:提供一个物理的时钟
- 时间戳预言机(TSO):采用中心化的授时方式,所有协调者向中心化节点获取时钟
5.共识协议
1.Quorum NWR模型
三要素:
- N:在分布式存储系统中,有多少份备份数据
- W:代表一次成功的更新操作要求至少有w份数据写入成功
- R:代表一次成功的读数据操作要求至少有R份数据成功读取
为保证强一致性,需要满足:W+R>N
将CAP选择权给用户,用户可配置WRN值
2.RAFT协议
Raft协议是一种共识算法,即使出现部分节点故障,网络延时等情况,也不影响各节点,进而提高系统的整体可用性。一定意义上讲,RAFT也使用了Quorum机制。
组成元素
- Leader(领导者),系统中是一主多从。负责处理所有的客户端请求,并向follower同步请求日志,当日志同步到大多数节点上后,通知follower提交日志。
- Follower(跟随着),不会发送任何请求。接受并持久化Leader同步的日志,在Leader告知日志可以提交后,提交日志。当Leader出现故障时,主动推荐自己为Candidate。
- Candidate(备选者),Leader选举过程中的临时角色。向其他节点发送请求投票信息。 如果获得大多数选票,则晋升为Leader。
三者关系如下:
转换关系
- Log(日志):节点之间同步的信息,以只追加写的方式进行同步,解决了数据被覆盖的问题
- Term (任期号):单调递增,每个Term内最多只有一个Leader
- Committed(被提交):日志被复制到多数派节点,即可认为已经被提交
- Applied(被应用):日志被应用到本地状态机:执行了log中命令,修改了内存状态
运行过程
初始全为Follower,通过选举选出Leader。Leader强制覆盖Follower不同步的日志。
切主:Leader出现问题,需要进行重新选举(未收到Follower的相应)。需要老 leader先自杀重启,新leader再产生作用。
Stale读:leader切换时产生,因此需要保证读的强一致性
3.Paxos协议
- 与RAFT的区别: Multi-Paxos 可以并发修改日志,而Raft写日志操作必须是连续的;可以随机选主,不必最新最全的节点当选Leader
- 优势:写入并发性,所有节点都能写入
- 劣势:所有节点都没有完整最新的数据,回复流程复杂,需要同步历史记录
具体过程如下:
6.分布式实践
1.MapReduce
- Mapper:将输入分解为多个Job来并行处理。彼此间几乎没有依赖关系
- Shuffler:将maper结果打乱,防止数据倾斜
- Reducer:对map阶段的结果进行全局汇总
容错能力
- Mapper故障:由中心化节点重新发起调度,新起Mapper重跑job
- Reducer故障:重跑Mapper,代价大
2.分布式KV
将海量结构化数据根据Key分成不同的Region,每个Region构建一个单机KV数据库, Region之间形成Raft Groups,做到强一致
容错能力
Node故障:通过Raft Learner模式进行数据修复
弹性能力 当出现局部Key热点或数据膨胀时,Region可以进行Split操作,分成两个子Region,反之收缩时进行Merge操作
小结
本章介绍了许多分布式概念,收获很大,希望在之后开发中能应用到。附教程中的整体思路:
参考文献
- 字节跳动分布式理论教程