这是我参与「第四届青训营」笔记创作活动的第12天。
写在前面
分布式一致性协议是保证分布式系统的consistent特性的一大重要内容,学习和总结分布式一致性协议的算法可以有效理解分布式存储的背后的逻辑。
笔记正文
1. 分布式系统
挑战
- 数据规模大
- 服务可用性要求高
- 快速迭代
理想的分布式系统
- 高性能:可扩展、低时延、高吞吐
- 正确:一致性、易于理解
- 可靠:容错、高可用
案例
- HDFS
- KV
- 接口get -> value
- batchPut
- RPC
- DB Engine
2. 一致性与共识算法
1. 复制
- 一台机器会宕机
- 两个副本都可以接受请求
- 复制过程
- 主副本定期拷贝全量数据到从副本
- 主副本拷贝操作到从副本
- 复制操作
- 主副本把所有操作打包为log
- 所有log写入持久化,保存到磁盘
- 应用包装成状态机,只接收log作为input
- 主副本确认log已经成功写入到副本机器上,当状态机apply后返回客户端
- 主副本把所有操作打包为log
- 读操作
- 方案一:直接读状态机,要求写操作进入状态机后再返回client
- 方案二:写操作复制完成后直接返回,读操作Block等待所有pending log进入状态机
- 如果不遵循,可能存在刚刚写入的值读不到的情况
2. 一致性
- 一致性是一种模型
- 约束分布式系统如何向外界(应用)提供服务
- KV中常见的一致性模型
- 最终一致性:读取可能暂时读不到但是总会读到
- 线性一致性:最严格,线性执行
- Linearizability是最理想的一致性
- 复制协议——当失效发生
- 主副本失效切换
- 主副本是否真的失效
- 算法在这种场景下是否仍然正确
3. 从Raft入手
1. 共识算法
- 错误总是发生
- 共识协议不等于一致性
- 共识协议的一致性指线性一致性
2. Raft
- 复制状态机(RSM)
- Raft中所有的consensus都直接用log作为载体
- Committed Index
- Raft更新commmited index意味着index前所有log都提交给状态机
- committed index不持久,volatile状态机
- Raft流程
- Follower
- Candidate
- Leader
- Raft日志复制
- Raft节点失效
- Raft Term跨Term与安全性
- 安全性验证 TLA+ 形式验证
- Raft Leader Failure
4. 实现细节以及未来
- 方案一
- 写log倍commit,返回客户端成功
- 读操作写入一条log,状态机apply时返回client
- 增加log量
- 方案二
- log被commit了,返回客户端成功
- 读操作先等待所有committed log apply再读取状态机
- 优化写时延
- 方案三
- 写log被状态机apply, 返回给client
- 读操作直接读状态机
- 优化读时延
- 细节
- Raft不保证一直有一个leader
- 一个term至多一个
- 存在多个term的leader
- Raft不保证一直有一个leader