Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schedule: one operator only occupy one limit #3820

Merged
merged 20 commits into from
Jul 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ade1fb9
use O(1) to get WMA
bufferflies Apr 25, 2021
8e7965d
Merge branch 'master' of https://github.com/tikv/pd
bufferflies May 13, 2021
69ab5ff
Merge branch 'master' of https://github.com/tikv/pd
bufferflies May 19, 2021
6aae83a
Merge branch 'master' of https://github.com/tikv/pd
bufferflies May 25, 2021
41762f4
Merge branch 'master' of https://github.com/tikv/pd
bufferflies May 26, 2021
46199fa
add sonar file ignore code duplicated
bufferflies May 27, 2021
6d2d5e3
Merge branch 'master' of https://github.com/tikv/pd
bufferflies Jun 1, 2021
ed9d779
Merge branch 'master' of https://github.com/tikv/pd
bufferflies Jun 4, 2021
54b33d7
Merge branch 'master' of https://github.com/tikv/pd
bufferflies Jun 10, 2021
11010ad
Merge branch 'master' of https://github.com/tikv/pd
bufferflies Jun 16, 2021
83fd21a
Merge branch 'master' of https://github.com/tikv/pd
bufferflies Jun 24, 2021
46d2825
one operator should occupy one limit
bufferflies Jun 29, 2021
951873f
remove no need change
bufferflies Jun 29, 2021
a09b1d7
Merge branch 'master' into featuer/OperatorDecouple
bufferflies Jun 29, 2021
4766fcc
move scheduler OpKind to operator.go
bufferflies Jun 29, 2021
46dc3fc
replace opkind to get op producer by using LowBit
bufferflies Jun 30, 2021
0d8203f
pass uint test
bufferflies Jun 30, 2021
05c60e1
replace chinese link
bufferflies Jun 30, 2021
18b0caa
OperatorCount use O(1)
bufferflies Jun 30, 2021
bf1f8fc
Merge branch 'master' into featuer/OperatorDecouple
bufferflies Jul 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions server/cluster/coordinator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,19 @@ func (s *testCoordinatorSuite) TestBasic(c *C) {

op1 := newTestOperator(1, tc.GetRegion(1).GetRegionEpoch(), operator.OpLeader)
oc.AddWaitingOperator(op1)
c.Assert(oc.OperatorCount(op1.Kind()), Equals, uint64(1))
c.Assert(oc.OperatorCount(operator.OpLeader), Equals, uint64(1))
c.Assert(oc.GetOperator(1).RegionID(), Equals, op1.RegionID())

// Region 1 already has an operator, cannot add another one.
op2 := newTestOperator(1, tc.GetRegion(1).GetRegionEpoch(), operator.OpRegion)
oc.AddWaitingOperator(op2)
c.Assert(oc.OperatorCount(op2.Kind()), Equals, uint64(0))
c.Assert(oc.OperatorCount(operator.OpRegion), Equals, uint64(0))

// Remove the operator manually, then we can add a new operator.
c.Assert(oc.RemoveOperator(op1), IsTrue)
op3 := newTestOperator(1, tc.GetRegion(1).GetRegionEpoch(), operator.OpRegion)
oc.AddWaitingOperator(op3)
c.Assert(oc.OperatorCount(op3.Kind()), Equals, uint64(1))
c.Assert(oc.OperatorCount(operator.OpRegion), Equals, uint64(1))
c.Assert(oc.GetOperator(1).RegionID(), Equals, op3.RegionID())
}

Expand Down
25 changes: 13 additions & 12 deletions server/schedule/operator/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,23 @@ type OpKind uint32

// Flags for operators.
const (
// Include leader transfer.
OpLeader OpKind = 1 << iota
// Include peer addition or removal. This means that this operator may take a long time.
OpRegion
// Initiated by merge checker or merge scheduler. Note that it may not include region merge.
// the order describe the operator's producer and is very helpful to decouple scheduler or checker limit
OpMerge OpKind = 1 << iota
// Initiated by range scheduler.
OpRange
// Initiated by replica checker.
OpReplica
// Include region split. Initiated by rule checker if `kind & OpAdmin == 0`.
OpSplit
// Initiated by admin.
OpAdmin
// Initiated by hot region scheduler.
OpHotRegion
// Initiated by replica checker.
OpReplica
// Initiated by merge checker or merge scheduler. Note that it may not include region merge.
OpMerge
// Initiated by range scheduler.
OpRange
// Include peer addition or removal. This means that this operator may take a long time.
OpRegion
// Include leader transfer.
OpLeader
// Initiated by admin.
OpAdmin
rleungx marked this conversation as resolved.
Show resolved Hide resolved
opMax
)

Expand Down
10 changes: 10 additions & 0 deletions server/schedule/operator/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ func (o *Operator) Kind() OpKind {
return o.kind
}

// SchedulerKind return the highest OpKind even if the operator has many OpKind
// fix #3778
func (o *Operator) SchedulerKind() OpKind {
bufferflies marked this conversation as resolved.
Show resolved Hide resolved
// LowBit ref: https://en.wikipedia.org/wiki/Find_first_set
// 6(110) ==> 2(10)
// 5(101) ==> 1(01)
// 4(100) ==> 4(100)
return o.kind & (-o.kind)
}

// Status returns operator status.
func (o *Operator) Status() OpStatus {
return o.status.Status()
Expand Down
35 changes: 34 additions & 1 deletion server/schedule/operator/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (s *testOperatorSuite) TestInfluence(c *C) {
}

func (s *testOperatorSuite) TestOperatorKind(c *C) {
c.Assert((OpLeader | OpReplica).String(), Equals, "leader,replica")
c.Assert((OpLeader | OpReplica).String(), Equals, "replica,leader")
c.Assert(OpKind(0).String(), Equals, "unknown")
k, err := ParseOperatorKind("region,leader")
c.Assert(err, IsNil)
Expand Down Expand Up @@ -382,3 +382,36 @@ func (s *testOperatorSuite) TestCheck(c *C) {
c.Assert(op.Status(), Equals, SUCCESS)
}
}

func (s *testOperatorSuite) TestSchedulerKind(c *C) {
testdata := []struct {
op *Operator
expect OpKind
}{
{
op: s.newTestOperator(1, OpMerge|OpLeader|OpRegion),
expect: OpMerge,
}, {
op: s.newTestOperator(1, OpReplica|OpRegion),
expect: OpReplica,
}, {
op: s.newTestOperator(1, OpSplit|OpRegion),
expect: OpSplit,
}, {
op: s.newTestOperator(1, OpRange|OpRegion),
expect: OpRange,
}, {
op: s.newTestOperator(1, OpHotRegion|OpLeader|OpRegion),
expect: OpHotRegion,
}, {
op: s.newTestOperator(1, OpRegion|OpLeader),
expect: OpRegion,
}, {
op: s.newTestOperator(1, OpLeader),
expect: OpLeader,
},
}
for _, v := range testdata {
c.Assert(v.op.SchedulerKind(), Equals, v.expect)
}
}
15 changes: 5 additions & 10 deletions server/schedule/operator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,21 +769,16 @@ func (oc *OperatorController) updateCounts(operators map[uint64]*operator.Operat
delete(oc.counts, k)
}
for _, op := range operators {
oc.counts[op.Kind()]++
oc.counts[op.SchedulerKind()]++
HunDunDM marked this conversation as resolved.
Show resolved Hide resolved
}
}

// OperatorCount gets the count of operators filtered by mask.
func (oc *OperatorController) OperatorCount(mask operator.OpKind) uint64 {
// OperatorCount gets the count of operators filtered by kind.
// kind only has one OpKind.
func (oc *OperatorController) OperatorCount(kind operator.OpKind) uint64 {
oc.RLock()
defer oc.RUnlock()
var total uint64
for k, count := range oc.counts {
if k&mask != 0 {
total += count
}
}
return total
return oc.counts[kind]
}

// GetOpInfluence gets OpInfluence.
Expand Down
2 changes: 1 addition & 1 deletion server/schedulers/balance_region.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (s *balanceRegionScheduler) EncodeConfig() ([]byte, error) {
}

func (s *balanceRegionScheduler) IsScheduleAllowed(cluster opt.Cluster) bool {
allowed := s.opController.OperatorCount(operator.OpRegion)-s.opController.OperatorCount(operator.OpMerge) < cluster.GetOpts().GetRegionScheduleLimit()
allowed := s.opController.OperatorCount(operator.OpRegion) < cluster.GetOpts().GetRegionScheduleLimit()
if !allowed {
operator.OperatorLimitCounter.WithLabelValues(s.GetType(), operator.OpRegion.String()).Inc()
}
Expand Down