Raft 协议分析与实战:构建自己的分布式缓存

hashicorp/raft的应用实战与分析

Posted by pandaychen on April 15, 2022

0x00 前言

0x01 验证

按照如下组成一个raft集群:

raft节点 端口 peer端口 存储目录
Node-1 6000 7000 node0
Node-2 6001 7001 node1
Node-3 6002 7002 node2

1、启动集群,并成为leader

[root@VM_120_245_centos ~/stcache]# ./stcached --http=127.0.0.1:6000 --raft=127.0.0.1:7000 --node=./node0 -bootstrap=true


stCached: 2022/07/29 18:08:53 http server listen:127.0.0.1:6000
2022-07-29T18:08:53.158+0800 [INFO]  raft: initial configuration: index=0 servers=[]
2022-07-29T18:08:53.158+0800 [INFO]  raft: entering follower state: follower="Node at 127.0.0.1:7000 [Follower]" leader-address= leader-id=
2022-07-29T18:08:54.395+0800 [WARN]  raft: heartbeat timeout reached, starting election: last-leader-addr= last-leader-id=
2022-07-29T18:08:54.396+0800 [INFO]  raft: entering candidate state: node="Node at 127.0.0.1:7000 [Candidate]" term=2
2022-07-29T18:08:54.413+0800 [DEBUG] raft: votes: needed=1
2022-07-29T18:08:54.413+0800 [DEBUG] raft: vote granted: from=127.0.0.1:7000 term=2 tally=1
2022-07-29T18:08:54.413+0800 [INFO]  raft: election won: tally=1
2022-07-29T18:08:54.413+0800 [INFO]  raft: entering leader state: leader="Node at 127.0.0.1:7000 [Leader]"
stCached: 2022/07/29 18:08:54 become leader, enable write api #成为leader

2、启动第2个节点

[root@VM_120_245_centos ~/blog_backup/stcache/stcache]# ./stcached --http=127.0.0.1:6001 --raft=127.0.0.1:7001 --node=./node1 --join=127.0.0.1:6000
stCached: 2022/07/29 18:10:35 http server listen:127.0.0.1:6001
2022-07-29T18:10:35.580+0800 [INFO]  raft: initial configuration: index=0 servers=[]
2022-07-29T18:10:35.580+0800 [INFO]  raft: entering follower state: follower="Node at 127.0.0.1:7001 [Follower]" leader-address= leader-id=
2022-07-29T18:10:35.592+0800 [WARN]  raft: failed to get previous log: previous-index=3 last-index=0 error="log not found"
2022-07-29T18:11:08.417+0800 [ERROR] raft: failed to take snapshot: error="nothing new to snapshot"

3、启动第3个节点

[root@VM_120_245_centos ~/blog_backup/stcache/stcache]# ./stcached --http=127.0.0.1:6002 --raft=127.0.0.1:7002 --node=./node2 --join=127.0.0.1:6000
stCached: 2022/07/29 18:10:55 http server listen:127.0.0.1:6002
2022-07-29T18:10:55.231+0800 [INFO]  raft: initial configuration: index=0 servers=[]
2022-07-29T18:10:55.231+0800 [INFO]  raft: entering follower state: follower="Node at 127.0.0.1:7002 [Follower]" leader-address= leader-id=
2022-07-29T18:10:55.239+0800 [WARN]  raft: failed to get previous log: previous-index=4 last-index=0 error="log not found"

节点2、节点3加入集群后,leader日志: raft-1

4、写入/读取数据:

[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6000/set?key=abc&value=efg"
ok
[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6000/get?key=abc"
efg
[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6001/get?key=abc"
efg
[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6002/get?key=abc"
efg
[root@VM_120_245_centos ~]# 

5、不可以向非leader写入数据

[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6001/set?key=abc&value=efg"
write method not allowed
[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6002/set?key=abc&value=efg"
write method not allowed

6、写入数据时leader/follower的状态变化

leader写入数据
raft-2

节点2(follower1)
raft-2

节点3(follower2)
raft-2

7、关闭leader节点
关闭节点1后,节点3通过选举成为了新的leader

raft-3

节点3可写:

[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6002/set?key=cba&value=gfe"
ok

8、查询follower变迁及数据

[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6001/get?key=cba"
gfe

9、将节点1重启,再加入集群,自动变为follower raft-3

leader状态: raft-3

再查询节点1的数据:

[root@VM_120_245_centos ~]# curl "http://127.0.0.1:6000/get?key=cba"
gfe

参考