fix issue replica selector v2 not compatible with v1 in mixed mode (#1269)

* fix issue replica selector v2 not compatible with v1 in mixed mode

Signed-off-by: crazycs520 <crazycs520@gmail.com>

* add prefer-leader test case

Signed-off-by: crazycs520 <crazycs520@gmail.com>

---------

Signed-off-by: crazycs520 <crazycs520@gmail.com>
This commit is contained in:
crazycs 2024-04-08 11:18:55 +08:00 committed by GitHub
parent abc9bb2878
commit 8fc819c1ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 75 additions and 8 deletions

View File

@ -79,6 +79,9 @@ func newReplicaSelectorV2(
for _, op := range opts {
op(&option)
}
if req.ReplicaReadType == kv.ReplicaReadPreferLeader {
WithPerferLeader()(&option)
}
return &replicaSelectorV2{
baseReplicaSelector: baseReplicaSelector{
regionCache: regionCache,
@ -166,17 +169,10 @@ func (s *replicaSelectorV2) nextForReplicaReadMixed(req *tikvrpc.Request) {
return
}
}
preferLeader := req.ReplicaReadType == kv.ReplicaReadPreferLeader
if s.attempts > 1 {
if req.ReplicaReadType == kv.ReplicaReadMixed {
// For mixed read retry, prefer retry leader first.
preferLeader = true
}
}
strategy := ReplicaSelectMixedStrategy{
leaderIdx: leaderIdx,
tryLeader: req.ReplicaReadType == kv.ReplicaReadMixed || req.ReplicaReadType == kv.ReplicaReadPreferLeader,
preferLeader: preferLeader,
preferLeader: s.option.preferLeader,
leaderOnly: s.option.leaderOnly,
learnerOnly: req.ReplicaReadType == kv.ReplicaReadLearner,
labels: s.option.labels,
@ -201,6 +197,14 @@ func (s *replicaSelectorV2) nextForReplicaReadMixed(req *tikvrpc.Request) {
req.StaleRead = false
req.ReplicaRead = s.isReadOnlyReq
}
// Monitor the flows destination if selector is under `ReplicaReadPreferLeader` mode.
if s.option.preferLeader {
if s.target.peer.Id != s.region.GetLeaderPeerID() {
s.target.store.recordReplicaFlowsStats(toFollower)
} else {
s.target.store.recordReplicaFlowsStats(toLeader)
}
}
}
}

View File

@ -663,6 +663,69 @@ func TestReplicaReadAccessPathByCase(t *testing.T) {
},
}
s.True(s.runCaseAndCompare(ca))
s.changeRegionLeader(3)
ca = replicaSelectorAccessPathCase{
reqType: tikvrpc.CmdGet,
readType: kv.ReplicaReadMixed,
staleRead: false,
accessErr: []RegionErrorType{ServerIsBusyErr, ServerIsBusyErr, ServerIsBusyErr},
expect: &accessPathResult{
accessPath: []string{
"{addr: store1, replica-read: true, stale-read: false}",
"{addr: store2, replica-read: true, stale-read: false}",
"{addr: store3, replica-read: true, stale-read: false}",
},
respErr: "",
respRegionError: fakeEpochNotMatch,
backoffCnt: 1,
backoffDetail: []string{"tikvServerBusy+1"},
regionIsValid: false,
},
}
s.True(s.runCaseAndCompare(ca))
ca = replicaSelectorAccessPathCase{
reqType: tikvrpc.CmdGet,
readType: kv.ReplicaReadPreferLeader,
staleRead: false,
accessErr: []RegionErrorType{ServerIsBusyErr, ServerIsBusyErr, ServerIsBusyErr},
expect: &accessPathResult{
accessPath: []string{
"{addr: store3, replica-read: true, stale-read: false}",
"{addr: store1, replica-read: true, stale-read: false}",
"{addr: store2, replica-read: true, stale-read: false}",
},
respErr: "",
respRegionError: fakeEpochNotMatch,
backoffCnt: 1,
backoffDetail: []string{"tikvServerBusy+1"},
regionIsValid: false,
},
}
s.True(s.runCaseAndCompare(ca))
ca = replicaSelectorAccessPathCase{
reqType: tikvrpc.CmdGet,
readType: kv.ReplicaReadPreferLeader,
staleRead: false,
label: &metapb.StoreLabel{Key: "id", Value: "2"},
accessErr: []RegionErrorType{ServerIsBusyErr, ServerIsBusyErr, ServerIsBusyErr},
expect: &accessPathResult{
accessPath: []string{
"{addr: store2, replica-read: true, stale-read: false}",
"{addr: store3, replica-read: true, stale-read: false}",
"{addr: store1, replica-read: true, stale-read: false}",
},
respErr: "",
respRegionError: fakeEpochNotMatch,
backoffCnt: 1,
backoffDetail: []string{"tikvServerBusy+1"},
regionIsValid: false,
},
}
s.True(s.runCaseAndCompare(ca))
s.changeRegionLeader(1)
}
func TestReplicaReadAccessPathByCase2(t *testing.T) {