Skip to content

Commit 3a13982

Browse files
committed
stability enhancement during overload conditions
Signed-off-by: shenmu.wy <[email protected]>
1 parent 05b8563 commit 3a13982

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

server/etcdserver/util.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"time"
2020

21+
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
2122
"go.etcd.io/etcd/client/pkg/v3/types"
2223
"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
2324
"go.etcd.io/etcd/server/v3/etcdserver/api/rafthttp"
@@ -42,6 +43,26 @@ func isConnectedFullySince(transport rafthttp.Transporter, since time.Time, self
4243
return numConnectedSince(transport, since, self, members) == len(members)
4344
}
4445

46+
// isTooManyRequest checks whether the gap between applied index and committed
47+
// index is too large. r *pb.InternalRaftRequest should read-only.
48+
func isTooManyRequest(ai, ci uint64, r *pb.InternalRaftRequest) bool {
49+
// Critical request kinds include LeaseRevoke
50+
isCritical := r != nil && r.LeaseRevoke != nil
51+
52+
// If the gap is larger than maxGapBetweenApplyAndCommitIndex, reject all normal request
53+
if !isCritical && ci > ai+maxGapBetweenApplyAndCommitIndex {
54+
return true
55+
}
56+
57+
// Make an extra 10% gap buffer for critical requests, so thay can be applied
58+
// during overload conditions.
59+
if isCritical && ci-ai > maxGapBetweenApplyAndCommitIndex+500 {
60+
return true
61+
}
62+
63+
return false
64+
}
65+
4566
// numConnectedSince counts how many members are connected to the local member
4667
// since the given time.
4768
func numConnectedSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) int {

server/etcdserver/util_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import (
1919
"testing"
2020
"time"
2121

22+
"github.com/stretchr/testify/assert"
2223
"go.uber.org/zap/zaptest"
2324

25+
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
2426
"go.etcd.io/etcd/client/pkg/v3/types"
2527
"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
2628
"go.etcd.io/etcd/server/v3/etcdserver/api/rafthttp"
@@ -110,3 +112,54 @@ type testStringerFunc func() string
110112
func (s testStringerFunc) String() string {
111113
return s()
112114
}
115+
116+
func TestIsTooManyRequest(t *testing.T) {
117+
tests := []struct {
118+
ci uint64
119+
ai uint64
120+
expect bool
121+
req *pb.InternalRaftRequest
122+
desc string
123+
}{
124+
{
125+
ci: 1 + maxGapBetweenApplyAndCommitIndex,
126+
ai: 1,
127+
expect: false,
128+
req: nil,
129+
desc: "Test nil InternalRaftRequest",
130+
},
131+
{
132+
ci: 1 + maxGapBetweenApplyAndCommitIndex,
133+
ai: 1,
134+
expect: false,
135+
req: &pb.InternalRaftRequest{},
136+
desc: "Test non-critical request and gap is not larger than maxGapBetweenApplyAndCommitIndex",
137+
},
138+
{
139+
ci: 1 + maxGapBetweenApplyAndCommitIndex + 1,
140+
ai: 1,
141+
expect: true,
142+
req: &pb.InternalRaftRequest{},
143+
desc: "Test non-critical request and gap is larger than maxGapBetweenApplyAndCommitIndex",
144+
},
145+
{
146+
ci: 1 + maxGapBetweenApplyAndCommitIndex + 1,
147+
ai: 1,
148+
expect: false,
149+
req: &pb.InternalRaftRequest{LeaseRevoke: &pb.LeaseRevokeRequest{}},
150+
desc: "Test critical request and gap is larger than maxGapBetweenApplyAndCommitIndex",
151+
},
152+
{
153+
ci: 1 + maxGapBetweenApplyAndCommitIndex + 1 + maxGapBetweenApplyAndCommitIndex/10,
154+
ai: 1,
155+
expect: true,
156+
req: &pb.InternalRaftRequest{LeaseRevoke: &pb.LeaseRevokeRequest{}},
157+
desc: "Test critical request and gap is larger than 110% maxGapBetweenApplyAndCommitIndex",
158+
},
159+
}
160+
161+
for _, test := range tests {
162+
t.Log(test.desc)
163+
assert.Equal(t, test.expect, isTooManyRequest(test.ai, test.ci, test.req))
164+
}
165+
}

server/etcdserver/v3_server.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,8 @@ func (s *EtcdServer) doSerialize(ctx context.Context, chk func(*auth.AuthInfo) e
792792
func (s *EtcdServer) processInternalRaftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (*apply2.Result, error) {
793793
ai := s.getAppliedIndex()
794794
ci := s.getCommittedIndex()
795-
if ci > ai+maxGapBetweenApplyAndCommitIndex {
795+
796+
if isTooManyRequest(ai, ci, &r) {
796797
return nil, errors.ErrTooManyRequests
797798
}
798799

0 commit comments

Comments
 (0)