瀏覽代碼

raft: Make MsgAppRes ack only the last index in MsgApp

As explained in #1366, the leader will fail to transmit the missed
logs if the leader receives a hearbeat response from a follower
that is not yet matched in the leader. In other words, there are
append responses that do not explicitly reject an append but
implied a gap.

This commit is based on @xiangli-cmu's idea. We should only acknowledge
upto the index of logs in the append message. This way responses to
heartbeats would never interfer with the log synchronization because
their log index is always 0.

Fixes #1366
Soheil Hassas Yeganeh 11 年之前
父節點
當前提交
233617bea2
共有 1 個文件被更改,包括 8 次插入1 次删除
  1. 8 1
      raft/raft.go

+ 8 - 1
raft/raft.go

@@ -380,7 +380,11 @@ func (r *raft) Step(m pb.Message) error {
 
 
 func (r *raft) handleAppendEntries(m pb.Message) {
 func (r *raft) handleAppendEntries(m pb.Message) {
 	if r.raftLog.maybeAppend(m.Index, m.LogTerm, m.Commit, m.Entries...) {
 	if r.raftLog.maybeAppend(m.Index, m.LogTerm, m.Commit, m.Entries...) {
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.lastIndex()})
+		mlastIndex := m.Index
+		if len(m.Entries) != 0 {
+			mlastIndex = m.Entries[len(m.Entries)-1].Index
+		}
+		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: mlastIndex})
 	} else {
 	} else {
 		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: m.Index, Reject: true})
 		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: m.Index, Reject: true})
 	}
 	}
@@ -428,6 +432,9 @@ func stepLeader(r *raft, m pb.Message) {
 		r.appendEntry(e)
 		r.appendEntry(e)
 		r.bcastAppend()
 		r.bcastAppend()
 	case pb.MsgAppResp:
 	case pb.MsgAppResp:
+		if m.Index == 0 {
+			return
+		}
 		if m.Reject {
 		if m.Reject {
 			if r.prs[m.From].maybeDecrTo(m.Index) {
 			if r.prs[m.From].maybeDecrTo(m.Index) {
 				r.sendAppend(m.From)
 				r.sendAppend(m.From)