这是我参与「第四届青训营 」笔记创作活动的的第15天
- 分布式系统
- 挑战
- 数据规模越来越大
- 服务的可用性要求越来越高
- 快速迭代的业务要求系统足够易用
- 目标
- 高性能
- 可拓展、低时延、高吞吐
- 正确
- 一致性、易于理解
- 可靠
- 容错、高可用
- 高性能
- 挑战
- 一致性与共识算法
- 从复制开始
- 主副本定期拷贝全量数据到从副本
- 代价太高
- 主副本拷贝操作到从副本
- 主副本把所有的操作打包成Log
- 应用包装成状态机,只接收Log作为Input
- 主副本确认Log已经成功写入到副本机器上,当状态机apply后,返回客户端
- 读操作
- 方案一
- 直接读状态机,要求写操作进入状态机后再返回client
- 方案二
- 写操作复制完成后直接返回,读操作block等待所有pending log进入状态机
- 方案一
- 主副本定期拷贝全量数据到从副本
- 什么是一致性
- 对于KV
- 要读到最近写入的值
- 一致性是一种模型(语义)
- 来约定一个分布式系统如何向外界(应用)提供服务
- KV中常见的一致性模型
- 最终一致性
- 读取可能暂时读不到但是总会读到
- 线性一致性
- 最严格、线性执行
- 最终一致性
- 对于KV
- 共识算法
- 一个值一旦确定,所有人都认同
- 共识协议不等于一致性
- 应用层面不同的一致性,都可以用共识协议来实现
- 比如可以故意返回旧的值
- 简单的复制协议也可以提供线性一致性
- 应用层面不同的一致性,都可以用共识协议来实现
- 一般讨论共识协议时提到的一致性,都指线性一致性
- 因为弱一致性往往可以使用相对简单的复制算法实现
- 从复制开始
- 从Raft入手
- Paxos
- 难以理解
- Raft
- 易于理解作为算法的设计目标
- 使用了RSM、Log、RPC的概念
- 直接使用RPC对算法进行了描述
- Strong Leader-based
- 使用了随机的方法来减少约束
- 正确性
- 形式化验证
- 拥有大量成熟系统
- 易于理解作为算法的设计目标
- 复制状态机RSM
- RSM(replicated state machine)
- raft中所有的consensus都是直接使用Log作为载体的
- Commited Index
- 一旦raft更新commited index,意味着这个index前的所有log都可以提交给状态机了
- commited index是不持久化的,状态机也是volatile的,重启后从第一条log开始
- RSM(replicated state machine)
- raft角色
- leader
- 所有操作的发起者
- candidate
- 参与竞选leader
- follower
- 不接收用户的请求,无主时成为candidate发起选主请求
- leader
- raft term
- 逻辑时钟
- 特点
- 每个leader服务于一个term
- 每个term至多只有一个leader
- 每个节点存储当前的term
- 每个节点term从一开始,只增不减
- 所有rpc的request response都携带term
- 只commit本term内的log
- raft主节点失效
- leader定期的发送AppendEntries RPCs给其余所有节点
- 如果follower有一段时间没有收到leader的AppendEntries,则转换身份成为candidate
- candidate自增自己的term,同时使用requestVote RPCs向剩余节点请求投票
- raft在检查自己是否可以投票时,会检查log是否outdated,至少不比本身旧才会投给对应的candidate
- 如果多数派节点投给它,则成为该term的leader
- raft安全性
- 同term
- 对于term内的安全性
- 目标
- 对于所有已经commited的<term,index>位置上至多只有一条log
- 目标
- 由于raft的多数派选举,我们可以保证在一个term中只有一个leader
- 在任何<term,index>位置上,至多只有一条log
- 对于term内的安全性
- 跨term
- 目标
- 如果一个log被标记commited,那这个log一定会在未来所有的leader中出现leader completeness
- 证明
- raft选举时会检查log是否outdated,只有最新的才能当选leader
- 选举需要多数派投票,而commited log也已经在多数派中(必有overlap)
- 新leader一定持有commited log,且leader永远不会overwrite log
- 目标
- 同term
- Paxos
- 实现细节以及未来
- 一致性读写
- 方案一
- 写log被commit了,返回客户端成功
- 读操作也写入一条log,状态机apply时返回client
- 增加log量
- 方案二
- 写log被commit了,返回客户端成功
- 读操作先等待所有commited log apply,再读状态机
- 优化写时延
- 方案三
- 写log被状态机apply,返回给client
- 读操作直接读状态机
- 优化读时延
- 方案一
- 确定合法的leader
- 方案一
- 通过一轮心跳确认leadership
- 方案二
- 通过上一次心跳时间来保证接下来的有段时间内follower不会timeout
- 同时follower在这段时间内不进行投票
- 如果多数follower满足条件,那么在这段时间内则保证不会有新leader产生
- 方案一
- 水平扩展
- 增加raft组,通过key分区,一个raft负责一段key
- 未来展望
- 高性能
- 多节点提交
- Raft与Paxos相互移植
- 一致性读写