|
@@ -95,6 +95,7 @@ type raftNode struct {
|
|
|
term uint64
|
|
term uint64
|
|
|
lead uint64
|
|
lead uint64
|
|
|
|
|
|
|
|
|
|
+ tickMu *sync.Mutex
|
|
|
raftNodeConfig
|
|
raftNodeConfig
|
|
|
|
|
|
|
|
// a chan to send/receive snapshot
|
|
// a chan to send/receive snapshot
|
|
@@ -131,6 +132,7 @@ type raftNodeConfig struct {
|
|
|
|
|
|
|
|
func newRaftNode(cfg raftNodeConfig) *raftNode {
|
|
func newRaftNode(cfg raftNodeConfig) *raftNode {
|
|
|
r := &raftNode{
|
|
r := &raftNode{
|
|
|
|
|
+ tickMu: new(sync.Mutex),
|
|
|
raftNodeConfig: cfg,
|
|
raftNodeConfig: cfg,
|
|
|
// set up contention detectors for raft heartbeat message.
|
|
// set up contention detectors for raft heartbeat message.
|
|
|
// expect to send a heartbeat within 2 heartbeat intervals.
|
|
// expect to send a heartbeat within 2 heartbeat intervals.
|
|
@@ -149,6 +151,13 @@ func newRaftNode(cfg raftNodeConfig) *raftNode {
|
|
|
return r
|
|
return r
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// raft.Node does not have locks in Raft package
|
|
|
|
|
+func (r *raftNode) tick() {
|
|
|
|
|
+ r.tickMu.Lock()
|
|
|
|
|
+ r.Tick()
|
|
|
|
|
+ r.tickMu.Unlock()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// start prepares and starts raftNode in a new goroutine. It is no longer safe
|
|
// start prepares and starts raftNode in a new goroutine. It is no longer safe
|
|
|
// to modify the fields after it has been started.
|
|
// to modify the fields after it has been started.
|
|
|
func (r *raftNode) start(rh *raftReadyHandler) {
|
|
func (r *raftNode) start(rh *raftReadyHandler) {
|
|
@@ -161,7 +170,7 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
for {
|
|
for {
|
|
|
select {
|
|
select {
|
|
|
case <-r.ticker.C:
|
|
case <-r.ticker.C:
|
|
|
- r.Tick()
|
|
|
|
|
|
|
+ r.tick()
|
|
|
case rd := <-r.Ready():
|
|
case rd := <-r.Ready():
|
|
|
if rd.SoftState != nil {
|
|
if rd.SoftState != nil {
|
|
|
newLeader := rd.SoftState.Lead != raft.None && atomic.LoadUint64(&r.lead) != rd.SoftState.Lead
|
|
newLeader := rd.SoftState.Lead != raft.None && atomic.LoadUint64(&r.lead) != rd.SoftState.Lead
|
|
@@ -368,13 +377,13 @@ func (r *raftNode) resumeSending() {
|
|
|
p.Resume()
|
|
p.Resume()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// advanceTicksForElection advances ticks to the node for fast election.
|
|
|
|
|
-// This reduces the time to wait for first leader election if bootstrapping the whole
|
|
|
|
|
-// cluster, while leaving at least 1 heartbeat for possible existing leader
|
|
|
|
|
-// to contact it.
|
|
|
|
|
-func advanceTicksForElection(n raft.Node, electionTicks int) {
|
|
|
|
|
- for i := 0; i < electionTicks-1; i++ {
|
|
|
|
|
- n.Tick()
|
|
|
|
|
|
|
+// advanceTicks advances ticks of Raft node.
|
|
|
|
|
+// This can be used for fast-forwarding election
|
|
|
|
|
+// ticks in multi data-center deployments, thus
|
|
|
|
|
+// speeding up election process.
|
|
|
|
|
+func (r *raftNode) advanceTicks(ticks int) {
|
|
|
|
|
+ for i := 0; i < ticks; i++ {
|
|
|
|
|
+ r.tick()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -415,8 +424,8 @@ func startNode(cfg *ServerConfig, cl *membership.RaftCluster, ids []types.ID) (i
|
|
|
raftStatusMu.Lock()
|
|
raftStatusMu.Lock()
|
|
|
raftStatus = n.Status
|
|
raftStatus = n.Status
|
|
|
raftStatusMu.Unlock()
|
|
raftStatusMu.Unlock()
|
|
|
- advanceTicksForElection(n, c.ElectionTick)
|
|
|
|
|
- return
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return id, n, s, w
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
|
|
func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
|
|
@@ -449,7 +458,6 @@ func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membe
|
|
|
raftStatusMu.Lock()
|
|
raftStatusMu.Lock()
|
|
|
raftStatus = n.Status
|
|
raftStatus = n.Status
|
|
|
raftStatusMu.Unlock()
|
|
raftStatusMu.Unlock()
|
|
|
- advanceTicksForElection(n, c.ElectionTick)
|
|
|
|
|
return id, cl, n, s, w
|
|
return id, cl, n, s, w
|
|
|
}
|
|
}
|
|
|
|
|
|