type Entry struct {
Command interface{} //来自客户端的命令
Term int //接收到此命令的任期
}
定义节点模型
go
// A Go object implementing a single Raft peer.
type Raft struct {
mu sync.Mutex // Lock to protect shared access to this peer's state
peers []*labrpc.ClientEnd // RPC end points of all peers
persister *Persister // Object to hold this peer's persisted state
me int // this peer's index into peers[]
dead int32 // set by Kill()
state State
currentTerm int
electionResetEvent time.Time
electionTimeout time.Duration
votedFor int
votes int
commitIndex int
lastApplied int
logs []LogEntry
nextIndex []int
matchIndex []int
applyChan chan ApplyMsg
}
type LogEntry struct {
Term int
Command interface{}
}
type State int
const (
Follower State = iota
Leader
Candidate
)
如果 leaderCommit > commitIndex,将 commitIndex 设置为 min(leaderCommit, index of last new entry)
go
// Make
// the service or tester wants to create a Raft server. the ports
// of all the Raft servers (including this one) are in peers[]. this
// server's port is peers[me]. all the servers' peers[] arrays
// have the same order. persister is a place for this server to
// save its persistent state, and also initially holds the most
// recent saved state, if any. applyCh is a channel on which the
// tester or service expects Raft to send ApplyMsg messages.
// Make() must return quickly, so it should start goroutines
// for any long-running work.
func Make(peers []*labrpc.ClientEnd, me int,
persister *Persister, applyCh chan ApplyMsg) *Raft {
rf := &Raft{}
rf.peers = peers
rf.persister = persister
rf.me = me
// Your initialization code here (2A, 2B, 2C).
rf.state = Follower
rf.votes = 0
rf.votedFor = -1
rf.currentTerm = 0
rf.electionTimeout = time.Duration(150+rand.Intn(300)) * time.Millisecond
rf.electionResetEvent = time.Now()
rf.commitIndex = 0
rf.lastApplied = 0
rf.logs = make([]LogEntry, 0)
rf.applyChan = applyCh
// initialize from state persisted before a crash
rf.readPersist(persister.ReadRaftState())
// start ticker goroutine to start elections
go rf.ticker()
return rf
}