这是我参与「第四届青训营」笔记创作活动的第15天
0 引言
1 分布式系统
目前来讲分布式系统面临的挑战包括数据规模越来越大、服务的可用性要求越来越高、快速迭代的业务要求系统足够易用。
对于理想中的分布式系统包括高性能(可拓展、低时延、高吞吐)、正确(一致性、易于理解)、可靠(容错、高可用)。
分布式系统我们会想到HDFS(Hadoop分布式文件系统)包括了NameNode、DataNode和Client。
Client客户端通过RPC通讯协议与分布式系统交互(K-V)。
2 一致性与共识算法
分布式一致性写(复制)与读操作
- 主副本把所有的操作打包成Log,所有的Log写入都是持久化的,保存在磁盘上;
- 应用包装成状态机,只接收Log作为Input;
- 主副本确认Log已经成功写入到副本机器上,当状态机apply后,返回客户端。
读操作
- 方案一:直接读状态机,要求写操作进入状态机后再返回client
- 方案二:写操作复制完成后直接返回,读操作Block等待所有pending log进入状态机
一致性的含义
一致性是一种模型(或语义),来约定一个分布式系统如何向外界(应用)提供服务。比如Client客户端想读取分布式机器最近写入的值,那么就需要这种一致性需要。
KV中常见的一致性模型分类:最终一致性(读取可能暂时读不到但是总会读到)、线性一致性(最严格,线性执行)。Linearizability是最理想的。
复制协议
当主副本失效时,需要保证较高的可用性,少数节点挂了的情况下仍然可以工作(容错性)。
共识算法
在分布式系统中让所有节点达成共识达到数据一致性。
在分布式系统中错误总是发生,比如网络断开、分区、缓慢、重传、乱序CPU、IO等都机会停住,因此共识算法可以达到容错(falute-tolerance),使系统整体不会因为个别机器宕机而全盘奔溃。
共识协议不等于一致性:应用层面不同的一致性,都可以用共识协议来实现,比如可以故意返回旧的值。简单的复制协议也可以提供线性一致性。
一般讨论共识协议时提到的一致性,都指线性一致性,因为弱一致性往往可以使用相对简单的复制算法实现。
3 从Raft入手
与PaxoS难以理解不同,Raft易于理解作为算法的设计目标,使用了RSM、Log、RPC(直接使用RPC对算法进行了描述)的概念,有Strong Leader-based,使用了随机的方法减少约束。对于正确性使用形式化验证,拥有大量成熟系统。
复制状态机(RSM)
复制状态机(replicated state machine,RSM)在Raft中所有的consensus都是直接使用Log 作为载体。
Commited Index:一旦Raft更新Commited Index,意味着这个Index前的所有Log都可以提交给状态机了。Commited lndex是不持久化的,状态机也是volatile的,重启后从第一条Log开始。
Raft角色
某时刻某服务器节点处于这三个状态之一:leader、follower或者candidate。
在正常情况下,集群中只有一个leader并且其他的节点全部都是follower。
- Leader处理所有的客户端请求(如果一个客户端和follower通信,follower会将请求重定向给leader)。
- follower都是被动的,他们不会发送任何请求,只是简单的响应来自leader和candidate的请求。
- candidate是用来选举一个新的leader。
Raft整体流程 / Raft日志复制 / Raft从节点失效
Raft Term
每个leader服务于一个term,每个term至多只有一个leader(leader与term是一对多的关系)。
每个节点存储当前的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安全性–同/跨Term
对于同Term内的安全性,对于所有已经的commited的<term, index>位置上至多只有一条log。
对于跨Term的安全性,如果一个log被标记commited,那这个log一定会在未来所有的leader中出现。
由于Raft的多数派选举,我们可以保证在一个term中只有一个leader,在任何<term,index>位置上,至多只有一条log。
Raft安全性验证
Raft使用TLA+进行了验证,形式验证(Formal Method),对算法所有的状态进行遍历。
4 实现细节以及未来
案例K-V设计
方案一:写log被commit了,返回客户端成功;读操作先等待所有commited log apply,再读取状态机;优化写时延。
方案二:写Log被状态机apply,返回给client;读操作直接读状态机;优化读时延。
确定合法的Leadership:
方案一:通过一轮Heartbeat确认 Leadership(获取多数派的响应)
方案二:通过上一次Heartbeat时间来保证接下来的有段时间内follower不会timeout。同时follower在这段时间内不进行投票。如果多数follower满足条件,那么在这段时间内则保证不会有新的Leader产生。
参考引用
1. 分布式系列第一弹:分布式一致性!
2. 深度解析 Raft 分布式一致性协议
3.【大数据专场 学习资料六】第四届字节跳动青训营
4. 分布式一致性算法:Raft 算法(Raft论文翻译)