笔记导言
该系列笔记用于GO语言和RAFT算法学习
前部分介绍raft算法后部分介绍etcd代码
etcd源码来自github,版本主要为ectd-3.1.5
本文主要根据视频:
<<raft算法工程案例之etcd源码导读>>
<<解析分布式共识算法之Raft算法>>
以上视频作者主页:https://space.bilibili.com/317473362
<<Deep Dive: etcd - Xiang Li, Alibaba & Wenjia Zhang, Google>>
<<Deep Dive: etcd - Jingyi Hu, Google>>
<<Secrets of Running Etcd - Marek Siarkowicz, Google>>
以上视频作者主主页:https://www.youtube.com/@cncf
以及人工智能回答和其他资料总结
横向分布式
所谓横向分布,也就是依靠增加主机节点来完成任务
优势
数据备份
负载均衡提高性能
问题
如何保证不同节点之间数据的一致性
如何保证分布式系统的秩序
CAP
Consistency 一致性
写操作对于集群具有原子性
Availability 可用性
对于客户端而言,操作可以及时得到响应
Partiton tolerance 分区容错性
在网络分区不可靠的情况下,可以正常工作
一般而言,CAP理论强调的是三个性质只能满足最多两个
追求可用性时的一致性问题
即时一致性
倘若为了快速响应客户端诉求,服务端采用了异步机制同步任务,那么客户端的请求就可能在follower同步到写请求数据之前就到达follower,此时就会来不及读取新数据
并且还有网络波动引起的脑裂问题等一系列问题
顺序一致性
如果日志条目在不同节点上因为网络问题以不同的顺序进行复制和提交,那么当这些日志条目所代表的操作应用于状态机时,各个节点的状态将会出现不一致。例如,一个转账操作(A转给B)必须保证先于后续的读取操作执行,否则可能造成A账户余额减少之后才开始读取,从而得出错误的余额信息。
追求一致性时的可用性问题
为了避免以上两个一致性问题,可以采取 提交操作 + 数据同步串行化
也就是将数据提交请求发送到maser,maser先将数据写入本机再同步到其他follower,得到其他follower的答复之后才会回复给客户端,提交数据的唯一入口是maser
数据同步任务不再异步执行,而是与写请求串行化执行,这种方式保证了提交的数据在写入所有状态机之前阻塞客户端。
唯一问在于
当某个follower存在网络问题时,会拖累整个集群的提交程序,所以需要分布式一致性算法来解决各种问题,raft就是其中一种解决方案
raft解决了什么
Consistency
raft一般保证最终一致性(弱一致性
Availability
raft保证半数以上节点存活时,系统是稳定的
raft基本原则
多数派原则
一主多从
读写分离
- 读节点由任意节点提供写节点由leader提供
raft算法术语
leader 领导者
写操作入口,将写操作应用到自身预写日志后发起提议,并提交被多数派认可的决断
follower 追随者
需要对提交 提议 和 竞选 做出响应
condidate 候选人
处于竞选流程时的临时状态,最终会根据投票变成leader或者follower
finnal consistency 最终一致性
中强一致性,对于写请求,服务端保证最终能提供正确结果,但需要同步时间
immediate consistency 即时一致性
强一致性,服务端要求做到写入立即可读
write ahead log 预写日志
提议阶段时记录写请求
state machine 状态机
节点存储数据的戒指,提交阶段时应用预写日志的改变
proposal 提议
两阶段提交的第一阶段,leader向所有节点发出同步请求
commit 提交
两阶段提交的第二阶段,leader认可请求已经被系统采纳的动作
apply 应用
将预写日志中的写操作作用到状态机
term 任期
一个logic clock,用于表示leader更迭的概念,每个任期只有一个leader,任期和索引可以定位唯一的预写日志
index 索引
日志在预写日志数组中的位置,任期和索引可以定位唯一的预写日志
brain split 脑裂
同意个任期出现多个leader的情况
quorum 法定数
只要有一半以上数量的状态机,提议操作就通过
预写日志和状态机
状态机
状态机是节点实际存储日志的容器,写请求的最后一步是将结果写入状态机
读请求是从状态机或许数据
预写日志
每个请求在预写日志中都拥有索引,保证写请求的先后顺序最终一致,同时相同索引的内容应该一样
两阶段提交
-
提议(proposal)阶段,leader将写请求记录到预写日志,leader之后与其他节点分享
-
其他节点接受信息后对比自身预写日志判断是否请求可以写入自己的预写日志中
a. 日志索引正确且连续;
b. 日志条目的任期号不小于跟随者的相应条目。 -
当得到多数赞同后就进入提交(commit)状态,预写日志即刻被leader写入状态机,这样可以避免响应较慢的节点拖累提交速度。
-
之后leader通过心跳消息通知其他节点,其他节点会更新自己的Commit Index,并开始将处于自己Commit Index位置及之前的未提交日志条目应用到本地状态机。
领导者机制
leader通过心跳信息告知follower自己的存在
如果leader不存在了,或者任期达到,follower会参加竞选成为竞选人状态,其中日志足够新的竞选人会得到选票,半数以上的票数会成为leader,每次竞选大概如150ms到300ms之间,如果超时,任期数字会增加,发起新一次竞选
如果由于网络问题导致了多个leader,那么任期数字更小的接收到任期数字更大的心跳数据后,自动变为follower
不强制要求follower也将自己的心跳消息给leader也可能不需要,在etcd中leader是会接受follower心跳消息,来确认自己的任期是最新的
任期和索引可以定位唯一一笔日志