DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

etcd raft实现

原文链接

raft整体的含义

  • Raft集群中,每个server只有三种状态:leader,follower,candidate(选举)。
  • follower不会主动发送消息,只会接受和响应消息。
  • leader处理所有的客户端请求,如果follower接收到客户端的请求,则转发给leader。
  • candidate是选举状态。

Raft主要是有三点:

  • Leader Election: raft集群里是主从的,leader来进行所有操作,follower不会主动向集群内的其他节点发起请求。
  • Log Replication: leader处理来自客户端的请求,leader把自己的日志发向follower做复制
  • Safety: 只有含有最新的日志的节点可以成为leader,如果收到投票请求时,发现对方的日志没有自己的新,那么久投否决票。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
for {
// 略略略,准备 rd

select {
// TODO: maybe buffer the config propose if there exists one (the way
// described in raft dissertation)
// Currently it is dropped in Step silently.
case pm := <-propc: // proposal 是有结果的消息,应该是用来等待是否成功处理的
m := pm.m
m.From = r.id
err := r.Step(m) // 注意,Step 是一个函数,这个函数用来处理消息。但是不同的身份有不同的Step实现,点进去看一下default里的代码,就调用了。参见 raft.go->becomeFollower, raft.go->becomeCandidate等等里的stepXXX函数
if pm.result != nil {
pm.result <- err
close(pm.result)
}
case m := <-n.recvc: // 收到消息,这里的消息应该是不等待结果的
// filter out response message from unknown From.
if pr := r.getProgress(m.From); pr != nil || !IsResponseMsg(m.Type) {
r.Step(m)
}
case cc := <-n.confc: // 配置变更
// 略略略
case <-n.tickc: // 心跳和选举的timeout,参见doc.go
r.tick()
case readyc <- rd: // Ready是各种准备好的变更
// 略略略
case <-advancec: // 这个是用来确认Ready已经处理完的
// 略略略
case c := <-n.status: // TODO: 好像也是状态变更???
c <- getStatus(r)
case <-n.stop: // 那就是stop咯
close(n.done)
return
}
}

大致的几个分支部分