目录
参考文章
raft协议 | vision9527/raft-demo: 通过hashicorp-raft库手把手调试raft协议 (github.com) |
paxos协议 | |
中英文论文地址 | |
go夜读分享bilibili地址 |
通过hashicorp-raft库手把手调试raft协议。即 通过使用 hashicorp/raft 库构建的 kv服务,以打印 raft 算法每一步执行的日志来介绍 raft 算法的主要原理,让大家对 raft 算法的实现有更实际的理解。
大纲
- Raft 协议简介
- Raft 选举过程、日志复制流程讲解
- Raft 协议动画演示
- hashicorp/raft 源码讲解
- 调试选举和日志复制场景,通过打印日志来了解实际流程
一、Raft协议简介
-
Raft :一种为了【管理复制日志的一致性 】协议
-
复制状态机:每个状态机或系统如果初始状态一致,然后接受的改变状态的命令也一致,最后产生的结果状态也是相同。
二、Raft选举过程
- 选举过程图1(单个节点视角)
- 选举过程图2(整体视角)
三、Raft日志复制流程
- 日志格式:term + index + cmd + type 。任期+索引+命令+类型。
【解读】日志格式:term + index + cmd + type 。任期+索引+命令+类型。
即在索引为2的,第一个任期内发生命令y<-1
- 请求处理整体流程
【解析】
(1)请求发送到leader所在的Server服务器,进入到你编写的 raft模块(consensus 共识,一致看法。)
(2) raft模块会调用raft的库,先将日志屯起来,然后并行将分配到不同节点
(3)如果收到大多数的复制成功的响应,提交日志,获取到状态机(state machine),返回客户端。
- 请求处理详细流程(重点)
注:这里7. commit log 应该是在5. commit之后,但是因为commit策略的原因有一定延迟,所以从日志上看是在回复客户端以后
四、Raft协议动画演示
-
Raft系统运行可视化1 http://thesecretlivesofdata.com/raft
-
Raft系统运行可视化2 Raft Consensus Algorithm
五、hashicorp/raft源码讲解
-
hashicorp/raft库 GitHub - hashicorp/raft: Golang implementation of the Raft consensus protocol
-
raft启动流程
-
raft监听事件
六、运行hashicorp/raft库搭建的简单kv服务
-
编译:go build -mod vendor
-
启动node1: ./raft-demo --http_addr=127.0.0.1:7001 --raft_addr=127.0.0.1:7000 --raft_id=1 --raft_cluster=1/127.0.0.1:7000,2/127.0.0.1:8000,3/127.0.0.1:9000
-
启动node2: ./raft-demo --http_addr=127.0.0.1:8001 --raft_addr=127.0.0.1:8000 --raft_id=2 --raft_cluster=1/127.0.0.1:7000,2/127.0.0.1:8000,3/127.0.0.1:9000
-
启动node3: ./raft-demo --http_addr=127.0.0.1:9001 --raft_addr=127.0.0.1:9000 --raft_id=3 --raft_cluster=1/127.0.0.1:7000,2/127.0.0.1:8000,3/127.0.0.1:9000
-
set请求:curl http://127.0.0.1:7001/set?key=test_key&value=test_value
-
get请求:curl http://127.0.0.1:7001/get?key=test_key
七、调试场景
选举变化相关
-
集群启动后,follower等待一个随机election timeout时间变成candidate,然后发起投票,如果不能获得majority票数,则任期term会一直增加(未pre-vote情况)(branch: election-1)
-
集群启动后,follower等待一个随机election timeout时间变成candidate,然后发起投票,获得majority票数的节点变成leader (branch: election-2)
-
leader选举成功后发送heartbeat保持leader的地位(branch: election-3)
-
leader失去majority节点的heartbeat响应,退回到follower(branch: election-4)
日志复制相关
-
leader接收客户端请求,向集群内所有节点发送复制RPC,所有都正常响应 -> 正常commit,然后apply到状态机,最后返回客户端处理成功(branch: replicate-log-1)
-
leader接收客户端请求,向集群内所有节点发送复制RPC,majority正常响应 -> 正常commit,然后apply到状态机,最后返回客户端处理成功(branch: replicate-log-2)
-
leader接收客户端请求,向集群内所有节点发送复制RPC,少于majority正常响应 -> 不能commit(branch: replicate-log-3)
八、收获
-
hashicorp/raft源码
-
raft选举与日志复制
九、QA
纠正:3个节点宕机2个,剩下一个不可用,怎么处理请求的强一致?
答:这个时候服务应该是不可用的,当然如果要强行提供查询的服务,强一致肯定是无法保证的。