Browse Source

rafthttp: only use pipeline to send MsgSnap

The size of MsgSnap may be very big, e.g., 1G.
If its size is big and general streaming is used to send it, it may block
the following messages for several ten seconds, which interrupts the
heartbeat heavily.
Only use pipeline to send MsgSnap.
Yicheng Qin 10 years ago
parent
commit
78aa251ab2
1 changed files with 7 additions and 0 deletions
  1. 7 0
      rafthttp/peer.go

+ 7 - 0
rafthttp/peer.go

@@ -180,6 +180,11 @@ func (p *peer) Stop() {
 
 func (p *peer) pick(m raftpb.Message) (writec chan raftpb.Message, name string, size int) {
 	switch {
+	// Considering MsgSnap may have a big size, e.g., 1G, and will block
+	// stream for a long time, only use one of the N pipelines to send MsgSnap.
+	case isMsgSnap(m):
+		writec = p.pipeline.msgc
+		name, size = "pipeline", pipelineBufSize
 	case p.msgAppWriter.isWorking() && canUseMsgAppStream(m):
 		writec = p.msgAppWriter.msgc
 		name, size = "msgapp stream", streamBufSize
@@ -192,3 +197,5 @@ func (p *peer) pick(m raftpb.Message) (writec chan raftpb.Message, name string,
 	}
 	return
 }
+
+func isMsgSnap(m raftpb.Message) bool { return m.Type == raftpb.MsgSnap }