浅谈分布式一致性协议 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第15天,本篇笔记主要是关于第十五次大数据课程《浅谈分布式一致性协议》的课堂笔记
分布式系统
远程过程调用(RPC): 分布式系统中通常将不同组件,或者不同节点的交互使用 RPC 的方式进行封装,在调用方的视角一次远程过程调用不需要关心如何对请求和响应进行编码,也不用关心具体的网络传输。
理想中的分布式系统: 高性能:可拓展、低时延、高吞吐 正确:一致性、易于理解 可靠:容错、高可用
小结
- 背景:数据规模的不断增加,我们需要大规模分布式系统
- 维度:对于一个分布式系统,希望能有哪些特征
- 从KV入手,看看我们如何满足分布式系统的要求
一致性与共识算法
复制
由于一台机器可能会挂,所以需要副本。
如何复制?
- 主副本定期拷贝全量数据到从副本
- 主副本拷贝操作到从副本
- 复制操作:
- 主副本把所有的操作打包成Log
所有的Log写入都是持久化的,保存在磁盘上
- 应用包装成状态机,只接收Log作为Input
- 主副本确认Log已经成功写入到副本机器上,当状态机apply后,返回客户端
- 读操作
- 方案一:直接读状态机,要求写操作进入状态机后再返回client
- 方案二:写操作复制完成后直接返回,读操作Block等待所有pending log进入状态机
- 如果不遵循上述两周方案呢?
- 可能存在刚刚写入的值读不到的情况(在 Log中)
一致性
-
对于我们的KV,像操作一台机器一样,要读到最近写入的值。
-
一致性是一种模型(或语义),来约定一个分布式系统如何向外界(应用)提供服务。
-
KV中常见的一致性模型:
- 最终一致性:读取可能暂时读不到但是总会读到。
- 线性一致性:最严格,线性执行。
-
当主副本失效时,为了使得算法简单
- 我们人肉切换,只要足够快
- 我们还是可以保证较高的可用性。
-
但是如何保证主副本是真的失效了呢?
- 在切换的过程中,主副本又开始接收client 端的请求
- 两个主副本显然是不正确的,log会被覆盖写掉
- 我们希望算法能在这种场景下仍然保持正确
-
要是增加到三个节点呢?
- 能不能允许少数节点挂了的情况下,仍然可以工作
- falut-tolerance
共识算法:
一个值一旦确定,所有人都认同
- 共识协议不等于一致性
- 应用层面不同的一致性,都可以用共识协议来实现
- 比如可以故意返回旧的值
- 简单的复制协议也可以提供线性一致性
- 应用层面不同的一致性,都可以用共识协议来实现
- 一般讨论共识协议时提到的一致性,都指线性一致性
- 因为弱一致性往往可以使用相对简单的复制算法实现
共识算法案例:Raft:
复制状态机(RSM)
- RSM (replicated state machine)
- Raft中所有的consensus都是直接使用Log作为载体
- Commited Index
- 一旦 Raft更新Commited Index,意味着这个Index前的所有Log都可以提交给状态机了
- Commited Index是不持久化的,状态机也是volatile 的,重启后从第一条 Log开始 Raft角色:
Raft整体流程:
leader通过发送心跳告诉follower自己还没挂掉,如果一段时间没发则认为leader挂掉,重新选举leader
Raft日志复制:
Raft从结点失效:
Raft Term:
- 每个Leader服务于一个term
- 每个term至多只有一个leader
- 每个节点存储当前的term
- 每个节点term从一开始,只增不减
- 所有rpc的request reponse都携带term
- 只commit本term内的log
Raft主节点失效:
- Leader定期的发送AppendEntries RPCs给其余所有节点
- 如果Follower有一段时间没有收到Leader的AppendEntries,则转换身份成为Candidate
- Candidate自增自己的term,同时使用RequestVote RPCs向剩余节点请求投票
- raft在检查是否可以投票时,会检查log是否outdated ,至少不比本身旧才会投给对应的Candidate
- 如果多数派节点投给它,则成为该term的leader
Raft Leader failure:
Raft安全性-同Term:
- 对于Term内的安全性
- 目标:对于所有已经的commited的<term,index>位置上至多只有一条log
- 由于Raft的多数派选举,我们可以保证在一个term 中只有一个leader。
- 我们可以证明一条更严格的声明:在任何<term,index>位置上,至多只有一条log Raft安全性-跨Term:
- 对于跨Term的安全性
- 目标:如果个log被标记commited,那这个log一定会在未来所有的leader中出现Leader completeness
- 可以证明这个property
- Raft选举时会检查Log的是否outdated,只有最新的才能当选Leader
- 选举需要多数派投票,而commited log也已经在多数派中(必有overlap)
- 新Leader一定持有commited log ,且Leader永远不会overwrite log