44 "context"
55 "fmt"
66 "math"
7+ "math/rand"
78 "time"
89
910 . "github.com/pingcap/check"
@@ -14,7 +15,6 @@ import (
1415 "github.com/tikv/pd/server/core"
1516 "github.com/tikv/pd/server/schedule/operator"
1617 "github.com/tikv/pd/server/schedule/placement"
17- "github.com/tikv/pd/server/schedule/storelimit"
1818)
1919
2020type sequencer struct {
@@ -86,8 +86,6 @@ func (s *testScatterRegionSuite) checkOperator(op *operator.Operator, c *C) {
8686
8787func (s * testScatterRegionSuite ) scatter (c * C , numStores , numRegions uint64 , useRules bool ) {
8888 opt := mockoption .NewScheduleOptions ()
89- c .Assert (opt .SetAllStoresLimit (storelimit .AddPeer , 99999 ), IsNil )
90- c .Assert (opt .SetAllStoresLimit (storelimit .RemovePeer , 99999 ), IsNil )
9189 tc := mockcluster .NewCluster (opt )
9290
9391 // Add ordinary stores.
@@ -128,8 +126,6 @@ func (s *testScatterRegionSuite) scatter(c *C, numStores, numRegions uint64, use
128126
129127func (s * testScatterRegionSuite ) scatterSpecial (c * C , numOrdinaryStores , numSpecialStores , numRegions uint64 ) {
130128 opt := mockoption .NewScheduleOptions ()
131- c .Assert (opt .SetAllStoresLimit (storelimit .AddPeer , 99999 ), IsNil )
132- c .Assert (opt .SetAllStoresLimit (storelimit .RemovePeer , 99999 ), IsNil )
133129 tc := mockcluster .NewCluster (opt )
134130
135131 // Add ordinary stores.
@@ -217,10 +213,8 @@ func (s *testScatterRegionSuite) TestStoreLimit(c *C) {
217213 }
218214}
219215
220- func (s * testScatterRegionSuite ) TestScatterGroup (c * C ) {
216+ func (s * testScatterRegionSuite ) TestScatterGroupInConcurrency (c * C ) {
221217 opt := mockoption .NewScheduleOptions ()
222- c .Assert (opt .SetAllStoresLimit (storelimit .AddPeer , 99999 ), IsNil )
223- c .Assert (opt .SetAllStoresLimit (storelimit .RemovePeer , 99999 ), IsNil )
224218 tc := mockcluster .NewCluster (opt )
225219 // Add 5 stores.
226220 for i := uint64 (1 ); i <= 5 ; i ++ {
@@ -245,52 +239,49 @@ func (s *testScatterRegionSuite) TestScatterGroup(c *C) {
245239 },
246240 }
247241
242+ // We send scatter interweave request for each group to simulate scattering multiple region groups in concurrency.
248243 for _ , testcase := range testcases {
249244 c .Logf (testcase .name )
250245 ctx , cancel := context .WithCancel (context .Background ())
251246 scatterer := NewRegionScatterer (ctx , tc )
252247 regionID := 1
253248 for i := 0 ; i < 100 ; i ++ {
254249 for j := 0 ; j < testcase .groupCount ; j ++ {
255- _ , err := scatterer .Scatter (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ),
250+ scatterer .scatterRegion (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ),
256251 fmt .Sprintf ("group-%v" , j ))
257- c .Assert (err , IsNil )
258252 regionID ++
259253 }
260- // insert region with no group
261- _ , err := scatterer .Scatter (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ), "" )
262- c .Assert (err , IsNil )
263- regionID ++
264254 }
265255
266- for i := 0 ; i < testcase .groupCount ; i ++ {
267- // comparing the leader distribution
268- group := fmt .Sprintf ("group-%v" , i )
269- max := uint64 (0 )
270- min := uint64 (math .MaxUint64 )
271- groupDistribution , exist := scatterer .ordinaryEngine .selectedLeader .GetGroupDistribution (group )
272- c .Assert (exist , Equals , true )
273- for _ , count := range groupDistribution {
274- if count > max {
275- max = count
276- }
277- if count < min {
278- min = count
256+ checker := func (ss * selectedStores , expected uint64 , delta float64 ) {
257+ for i := 0 ; i < testcase .groupCount ; i ++ {
258+ // comparing the leader distribution
259+ group := fmt .Sprintf ("group-%v" , i )
260+ max := uint64 (0 )
261+ min := uint64 (math .MaxUint64 )
262+ groupDistribution , _ := ss .groupDistribution .Get (group )
263+ for _ , count := range groupDistribution .(map [uint64 ]uint64 ) {
264+ if count > max {
265+ max = count
266+ }
267+ if count < min {
268+ min = count
269+ }
279270 }
271+ c .Assert (math .Abs (float64 (max )- float64 (expected )), LessEqual , delta )
272+ c .Assert (math .Abs (float64 (min )- float64 (expected )), LessEqual , delta )
280273 }
281- // 100 regions divided 5 stores, each store expected to have about 20 regions.
282- c .Assert (min , LessEqual , uint64 (20 ))
283- c .Assert (max , GreaterEqual , uint64 (20 ))
284- c .Assert (max - min , LessEqual , uint64 (5 ))
285274 }
275+ // For leader, we expect each store have about 20 leader for each group
276+ checker (scatterer .ordinaryEngine .selectedLeader , 20 , 5 )
277+ // For peer, we expect each store have about 50 peers for each group
278+ checker (scatterer .ordinaryEngine .selectedPeer , 50 , 15 )
286279 cancel ()
287280 }
288281}
289282
290283func (s * testScatterRegionSuite ) TestScattersGroup (c * C ) {
291284 opt := mockoption .NewScheduleOptions ()
292- c .Assert (opt .SetAllStoresLimit (storelimit .AddPeer , 99999 ), IsNil )
293- c .Assert (opt .SetAllStoresLimit (storelimit .RemovePeer , 99999 ), IsNil )
294285 tc := mockcluster .NewCluster (opt )
295286 // Add 5 stores.
296287 for i := uint64 (1 ); i <= 5 ; i ++ {
@@ -370,3 +361,38 @@ func (s *testScatterRegionSuite) TestSelectedStoreGC(c *C) {
370361 _ , ok = stores .GetGroupDistribution ("testgroup" )
371362 c .Assert (ok , Equals , false )
372363}
364+
365+ // TestRegionFromDifferentGroups test the multi regions. each region have its own group.
366+ // After scatter, the distribution for the whole cluster should be well.
367+ func (s * testScatterRegionSuite ) TestRegionFromDifferentGroups (c * C ) {
368+ opt := mockoption .NewScheduleOptions ()
369+ tc := mockcluster .NewCluster (opt )
370+ // Add 6 stores.
371+ storeCount := 6
372+ for i := uint64 (1 ); i <= uint64 (storeCount ); i ++ {
373+ tc .AddRegionStore (i , 0 )
374+ }
375+ ctx , cancel := context .WithCancel (context .Background ())
376+ defer cancel ()
377+ scatterer := NewRegionScatterer (ctx , tc )
378+ regionCount := 50
379+ for i := 1 ; i <= regionCount ; i ++ {
380+ p := rand .Perm (storeCount )
381+ scatterer .scatterRegion (tc .AddLeaderRegion (uint64 (i ), uint64 (p [0 ])+ 1 , uint64 (p [1 ])+ 1 , uint64 (p [2 ])+ 1 ), fmt .Sprintf ("t%d" , i ))
382+ }
383+ check := func (ss * selectedStores ) {
384+ max := uint64 (0 )
385+ min := uint64 (math .MaxUint64 )
386+ for i := uint64 (1 ); i <= uint64 (storeCount ); i ++ {
387+ count := ss .totalCountByStore (i )
388+ if count > max {
389+ max = count
390+ }
391+ if count < min {
392+ min = count
393+ }
394+ }
395+ c .Assert (max - min , LessEqual , uint64 (2 ))
396+ }
397+ check (scatterer .ordinaryEngine .selectedPeer )
398+ }
0 commit comments