这是我参与「第五届青训营 」笔记创作活动的第9天
只不过是字节给我的任务罢了
分布式理论
分布式概述
分布式系统是计算机程序的集合,这些程序利用跨多个独立计算节点的计算资源来实现共同的目标。可以分为分布式计算、分布式存储、分布式数据库等。
优势:
- 去中心化
- 低成本
- 弹性
- 资源共享
- 可靠性高
挑战
- 普遍的节点故障
- 不可靠的网络
- 异构的机器与硬件环境
- 安全
常见分布式系统
Google File System谷歌分布式文件系统
Ceph:统一的分布式存储系统
Hadoop HDFS:基于GFS架构的开源分布式文件系统
Zookeeper:高可用
...
故障模型
- Byzantine failure:节点可以任意篡改发送给其他节点的数据
- Authentication detectable byzantine failure (ADB)Byzantine failure的特例;节点可以篡改数据,但不能伪造其他节点的数据
- Performance failure : 节点未在特定时间段内收到数据,即时间太早或太晚
- Omission failure : 节点收到数据的时间无限晚,即收不到数据
- Crash failure : 在omission failure的基础上,增加了节点停止响应的假设,也即持续性地omission failure
- Fail-stop failure : 在Crash failure的基础上增加了错误可检测的假设
拜占庭将军问题
三个将军对进攻/撤退进行投票
A观察敌情决定进攻
B观察敌情决定撤退
C观察敌情决定进攻
三人相互发送自己的意见,最终2票进攻,1票撤退,结果是进攻
如果C是叛徒(信息篡改)
给A发送进攻,给B发送撤退
这样A收到的就是2进攻1撤退,A最终进攻;B收到2撤退1进攻,B最终撤退。信息被篡改
解决方法:增加一个将军D,当做信息中枢,只负责分发消息,没有投票权,约定没有收到消息为撤退
第一轮,D收集A、B、C的投票,然后分发
第二轮,去除D,ABC相互发送意见
当有3m+1个将军,其中m个叛徒时,增加m轮协商就可以达成一致
共识和一致性
AB读,C写,因为C在写,有可能A、B读取的数据不一致,但是等C写入完成后,A、B读取的就是相同的数据了——最终一致性
当A读到C写入后的数据,及时地将消息同步到其他客户端,这样其他客户端就能立刻获取到写入后的数据——线性一致性
线性一致性会增加延迟,可用性受损
时间和事件顺序
如果有相同节点的两个事件a、b,a在b之前发生,则定义a->b
- 如果事件a表示某节点发送某条消息,B接收这条消息,则有a->b
- 如果有a->b且b->c,则有a->c
当且仅当a不能->b,b不能->a时,则称两个事件并发
Lamport逻辑时钟
对于每个节点Pi定义一个时钟Ci为一个函数,它为任意一个事件a赋值编号为Ci(a)
- 如果在相同节点Pi上的事件a在事件b之前发生,则有Ci(a)<Ci(b)
- 如果事件a表示节点Pi发送某条消息,b表示节点Pj接收这条消息,则有Ci(a)<Ci(b)
同一节点的连续两个事件之间,至少要有一条tick time(虚线表示)
利用逻辑时钟可以对系统中的事件进行全序排序
理论基础
CAP理论
C(Consistence)一致性,指数据在多个副本之间能够保持一致的特性(严格的一致性)
A(Availability)可用性,指系统提供的服务一致处于可用状态,每次请求都能获得到非错的响应——但是不保证获取最新的数据
P(Network partitioning)分区容错性,分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障
CAP不能同时满足
ACID理论
事务是数据库系统中非常重要的概念,是数据库管理系统执行过程中的一个逻辑单元,能够保证一个事务中的操作要么全部执行,要么全都不执行
- 原子性,指操作要么全成功,要么全失败回滚
- 一致性,指事务必须使数据库从一个一致性状态变换到另外一个一致性状态,因此事务的执行之前和之后都必须处于一个一致性状态
- 隔离性,多个用户并发访问数据库时,每个用户的事务之间不相互干扰,多个并发事务之间要相互隔离。
- 持久性,持久性指一个事务一旦被提交了,那么对数据库的改变是永久性的,即使数据库遭遇故障也不会丢失事务的操作。
BASE理论
本理论是对CAP中一致性和可用性权衡的结果。
- Basically Available(基本可用):出现不可预知的故障,但是还是能够使用
- Soft state(软状态):允许系统中的数据存在中间状态,即允许系统在多个不同节点的数据副本存在数据延时
- Eventually consistent(最终一致性)系统能够保证在没有新的更新的情况下,数据最终达到一致的状态,因此所有客户端对系统的数据访问能够获取到最新的值
分布式事务
-
两阶段提交,使所有节点进行事务提交时,保持一致性
-
分两个阶段Prepare、Commit
-
Prepare阶段:Coordinator向Participant发送Prepare请求,Participant回复Done
-
Commit阶段:Coordinator向Participant发送Commit请求,Participant回复Ack
- 如果Participant宕机,Coordinator则会发起Rollback请求,进行回滚操作
-
-
三阶段提交
-
将两阶段提交中的Prepare阶段拆成两部分:CanCommit和PreCommit
- 解决单点故障问题和阻塞问题
-
-
MVCC
- 悲观锁:操作数据时,把数据锁住,直到操作完成后才会释放锁,上锁期间其他人不能修改数据
- 乐观锁:不会上锁,只是在执行更新的时候判断别人是否修改数据,只有冲突时才会放弃操作
- MVCC是一种并发控制的方法,维持一个数据的版本使读写操作没有冲突,不阻塞读也不阻塞写,MVCC为每个修改保存一个版本,和事务的时间戳相关联。可以提高并发性能,解决脏读的问题
- 时间戳预言机(TSO),采用中心化的授时方式,所有协调者向中心化节点获取时钟。
共识协议
Quorum NWR模型
三要素
- N:分布式存储系统中,有多少份备份数据
- W:代表一次成功的更新操作至少有W份数据写入成功
- R:代表一次成功的读数据操作要求至少有R份数据成功读取
为了保证强一致性,需要保证W+R>N
RAFT协议
- Leader:通常一个系统中是一主多从。Leader处理所有的客户端请求,并向Follower同步请求日志,当日志同步到大多数节点上后,通知follower提交日志
- Follower:不会发送任何请求,接收并持久化Leader同步的日志,在Leader告知日志可以提交后,提交日志,当Leader出现故障时,主动推荐自己为Candidate
- Candidate:Leader选举过程中的临时角色。向其他节点发送请求投票信息。如果获得大多数投票,则晋升为Leader
- Log:节点之间同步的信息,以只追加写的方式进行同步,解决了数据被覆盖的问题
- Term(任期号):单调递增,每个Term内只有一个Leader
- Committed:日志被复制到多数派节点,即可认为已被提交
- Applied:日志被应用到本地状态机:执行了Log中命令,修改了内存状态
Leader选举过程
-
初始全部为Follower
-
Current Term + 1
-
选举自己
-
向其它参与者发起RequestVote请求,retry直到
- 收到多数派请求,成为Leader,并发送心跳
- 收到其它Leader的请求,转为Follower,更新自己的Term
- 收到部分,但未达到多数派,选举超时,随机timeout开始下一轮
Log Replication过程
新Leader产生,Leader和Follower不同步,Leader制覆盖Followers的不同步的日志
-
Leader收到写请求w
-
将w写入本地log
-
向其它Follower发起AppendEntries RPC
-
等待多数派回复
- 更新本地状态机,返回给客户端
- 下一个心跳通知Follower上一个Log已经被 Committed了
- Follower也根据命令应用本地状态机
-
Follower有问题,Leader一直retry
两个规则:
- 任期内每个参与者最多投一票(持久化)
- 要成为Leader,必须拿到多数投票
切换Leader
当Leader出现问题时,就需要进行重新选举
- Leader发现失去Follower的响应,失去Leader身份
- 两个Follower之间一段时间未收到心跳,重新进行选举,选出新的Leader,此时发生了切主
- Leader自杀重启,以Follower的身份加入进来
Stale读
- 发生Leader切换,old leader收到了读请求。如果直接响应,可能会有Stale Read
- 应该等到老Leader彻底死透了(Election timout>lease timeout),新Leader再上位