Skip to content

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,如果收到投票请求时,发现对方的日志没有自己的新,那么久投否决票。
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
    }
}

大致的几个分支部分