diff --git a/tools/pd-simulator/main.go b/tools/pd-simulator/main.go index 48602d10aa9..08348b6b519 100644 --- a/tools/pd-simulator/main.go +++ b/tools/pd-simulator/main.go @@ -206,7 +206,6 @@ EXIT: } fmt.Printf("%s [%s] total iteration: %d, time cost: %v\n", simResult, simCase, driver.TickCount(), time.Since(start)) - driver.PrintStatistics() if analysis.GetTransferCounter().IsValid { analysis.GetTransferCounter().PrintResult() } diff --git a/tools/pd-simulator/simulator/drive.go b/tools/pd-simulator/simulator/drive.go index 6968520c1bd..8d8133c4912 100644 --- a/tools/pd-simulator/simulator/drive.go +++ b/tools/pd-simulator/simulator/drive.go @@ -163,11 +163,6 @@ func (d *Driver) Check() bool { return d.simCase.Checker(d.raftEngine.regionsInfo, stats) } -// PrintStatistics prints the statistics of the scheduler. -func (d *Driver) PrintStatistics() { - d.raftEngine.schedulerStats.PrintStatistics() -} - // Start starts all nodes. func (d *Driver) Start() error { for _, n := range d.conn.Nodes { diff --git a/tools/pd-simulator/simulator/metrics.go b/tools/pd-simulator/simulator/metrics.go index 5f06b2cbb65..19e675c56a9 100644 --- a/tools/pd-simulator/simulator/metrics.go +++ b/tools/pd-simulator/simulator/metrics.go @@ -11,8 +11,26 @@ var ( Help: "Bucketed histogram of processing time (s) of handled snap requests.", Buckets: prometheus.ExponentialBuckets(0.0005, 2, 20), }, []string{"store", "type"}) + + schedulingCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "pd", + Subsystem: "schedule", + Name: "scheduling_count", + Help: "Counter of region scheduling", + }, []string{"type"}) + + snapshotCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "pd", + Subsystem: "schedule", + Name: "snapshot_count", + Help: "Counter of region snapshot", + }, []string{"store", "type"}) ) func init() { prometheus.MustRegister(snapDuration) + prometheus.MustRegister(schedulingCounter) + prometheus.MustRegister(snapshotCounter) } diff --git a/tools/pd-simulator/simulator/raft.go b/tools/pd-simulator/simulator/raft.go index cfd1e8719f0..45964eeecb2 100644 --- a/tools/pd-simulator/simulator/raft.go +++ b/tools/pd-simulator/simulator/raft.go @@ -32,7 +32,6 @@ type RaftEngine struct { regionsInfo *core.RegionsInfo conn *Connection regionChange map[uint64][]uint64 - schedulerStats *schedulerStatistics regionSplitSize int64 regionSplitKeys int64 storeConfig *SimConfig @@ -45,7 +44,6 @@ func NewRaftEngine(conf *cases.Case, conn *Connection, storeConfig *SimConfig) * regionsInfo: core.NewRegionsInfo(), conn: conn, regionChange: make(map[uint64][]uint64), - schedulerStats: newSchedulerStatistics(), regionSplitSize: conf.RegionSplitSize, regionSplitKeys: conf.RegionSplitKeys, storeConfig: storeConfig, diff --git a/tools/pd-simulator/simulator/statistics.go b/tools/pd-simulator/simulator/statistics.go deleted file mode 100644 index 2dadd78020d..00000000000 --- a/tools/pd-simulator/simulator/statistics.go +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2018 TiKV Project Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package simulator - -import ( - "fmt" - "math" - - "github.com/tikv/pd/pkg/syncutil" -) - -type taskStatistics struct { - syncutil.RWMutex - addVoter map[uint64]int - removePeer map[uint64]int - addLearner map[uint64]int - promoteLeaner map[uint64]int - demoteVoter map[uint64]int - transferLeader map[uint64]map[uint64]int - mergeRegion int -} - -func newTaskStatistics() *taskStatistics { - return &taskStatistics{ - addVoter: make(map[uint64]int), - removePeer: make(map[uint64]int), - addLearner: make(map[uint64]int), - promoteLeaner: make(map[uint64]int), - demoteVoter: make(map[uint64]int), - transferLeader: make(map[uint64]map[uint64]int), - } -} - -func (t *taskStatistics) getStatistics() map[string]int { - t.RLock() - defer t.RUnlock() - stats := make(map[string]int) - addVoter := getSum(t.addVoter) - removePeer := getSum(t.removePeer) - addLearner := getSum(t.addLearner) - promoteLearner := getSum(t.promoteLeaner) - demoteVoter := getSum(t.demoteVoter) - - var transferLeader int - for _, to := range t.transferLeader { - for _, v := range to { - transferLeader += v - } - } - - stats["Add Voter (task)"] = addVoter - stats["Remove Peer (task)"] = removePeer - stats["Add Learner (task)"] = addLearner - stats["Promote Learner (task)"] = promoteLearner - stats["Demote Voter (task)"] = demoteVoter - stats["Transfer Leader (task)"] = transferLeader - stats["Merge Region (task)"] = t.mergeRegion - - return stats -} - -func (t *taskStatistics) incAddVoter(regionID uint64) { - t.Lock() - defer t.Unlock() - t.addVoter[regionID]++ -} - -func (t *taskStatistics) incAddLearner(regionID uint64) { - t.Lock() - defer t.Unlock() - t.addLearner[regionID]++ -} - -func (t *taskStatistics) incPromoteLearner(regionID uint64) { - t.Lock() - defer t.Unlock() - t.promoteLeaner[regionID]++ -} - -func (t *taskStatistics) incDemoteVoter(regionID uint64) { - t.Lock() - defer t.Unlock() - t.demoteVoter[regionID]++ -} - -func (t *taskStatistics) incRemovePeer(regionID uint64) { - t.Lock() - defer t.Unlock() - t.removePeer[regionID]++ -} - -func (t *taskStatistics) incMergeRegion() { - t.Lock() - defer t.Unlock() - t.mergeRegion++ -} - -func (t *taskStatistics) incTransferLeader(fromPeerStoreID, toPeerStoreID uint64) { - t.Lock() - defer t.Unlock() - _, ok := t.transferLeader[fromPeerStoreID] - if ok { - t.transferLeader[fromPeerStoreID][toPeerStoreID]++ - } else { - m := make(map[uint64]int) - m[toPeerStoreID]++ - t.transferLeader[fromPeerStoreID] = m - } -} - -type snapshotStatistics struct { - syncutil.RWMutex - receive map[uint64]int - send map[uint64]int -} - -func newSnapshotStatistics() *snapshotStatistics { - return &snapshotStatistics{ - receive: make(map[uint64]int), - send: make(map[uint64]int), - } -} - -type schedulerStatistics struct { - taskStats *taskStatistics - snapshotStats *snapshotStatistics -} - -func newSchedulerStatistics() *schedulerStatistics { - return &schedulerStatistics{ - taskStats: newTaskStatistics(), - snapshotStats: newSnapshotStatistics(), - } -} - -func (s *snapshotStatistics) getStatistics() map[string]int { - s.RLock() - defer s.RUnlock() - maxSend := getMax(s.send) - maxReceive := getMax(s.receive) - minSend := getMin(s.send) - minReceive := getMin(s.receive) - - stats := make(map[string]int) - stats["Send Maximum (snapshot)"] = maxSend - stats["Receive Maximum (snapshot)"] = maxReceive - if minSend != math.MaxInt32 { - stats["Send Minimum (snapshot)"] = minSend - } - if minReceive != math.MaxInt32 { - stats["Receive Minimum (snapshot)"] = minReceive - } - - return stats -} - -func (s *snapshotStatistics) incSendSnapshot(storeID uint64) { - s.Lock() - defer s.Unlock() - s.send[storeID]++ -} - -func (s *snapshotStatistics) incReceiveSnapshot(storeID uint64) { - s.Lock() - defer s.Unlock() - s.receive[storeID]++ -} - -// PrintStatistics prints the statistics of the scheduler. -func (s *schedulerStatistics) PrintStatistics() { - task := s.taskStats.getStatistics() - snap := s.snapshotStats.getStatistics() - for t, count := range task { - fmt.Println(t, count) - } - for s, count := range snap { - fmt.Println(s, count) - } -} - -func getMax(m map[uint64]int) int { - var max int - for _, v := range m { - if v > max { - max = v - } - } - return max -} - -func getMin(m map[uint64]int) int { - min := math.MaxInt32 - for _, v := range m { - if v < min { - min = v - } - } - return min -} - -func getSum(m map[uint64]int) int { - var sum int - for _, v := range m { - sum += v - } - return sum -} diff --git a/tools/pd-simulator/simulator/task.go b/tools/pd-simulator/simulator/task.go index 14919d2768c..379707f4b3b 100644 --- a/tools/pd-simulator/simulator/task.go +++ b/tools/pd-simulator/simulator/task.go @@ -252,7 +252,7 @@ func (m *mergeRegion) tick(engine *RaftEngine, region *core.RegionInfo) (newRegi core.SetApproximateSize(targetRegion.GetApproximateSize()+region.GetApproximateSize()), core.SetApproximateKeys(targetRegion.GetApproximateKeys()+region.GetApproximateKeys()), ) - engine.schedulerStats.taskStats.incMergeRegion() + schedulingCounter.WithLabelValues("merge").Inc() return newRegion, true } @@ -274,11 +274,11 @@ func (t *transferLeader) tick(engine *RaftEngine, region *core.RegionInfo) (newR } newRegion = region.Clone(core.WithLeader(toPeer)) - engine.schedulerStats.taskStats.incTransferLeader(t.fromPeerStoreID, toPeer.GetStoreId()) + schedulingCounter.WithLabelValues("transfer-leader").Inc() return } -func checkAndCreateChangePeerOption(engine *RaftEngine, region *core.RegionInfo, +func checkAndCreateChangePeerOption(region *core.RegionInfo, peer *metapb.Peer, from, to metapb.PeerRole) []core.RegionCreateOption { // `from` and `to` need to satisfy the combination in switch. @@ -298,9 +298,9 @@ func checkAndCreateChangePeerOption(engine *RaftEngine, region *core.RegionInfo, // create option switch to { case metapb.PeerRole_Voter: // Learner/IncomingVoter -> Voter - engine.schedulerStats.taskStats.incPromoteLearner(region.GetID()) + schedulingCounter.WithLabelValues("promote-learner").Inc() case metapb.PeerRole_Learner: // Voter/DemotingVoter -> Learner - engine.schedulerStats.taskStats.incDemoteVoter(region.GetID()) + schedulingCounter.WithLabelValues("demote-voter").Inc() case metapb.PeerRole_IncomingVoter: // Learner -> IncomingVoter, only in joint state case metapb.PeerRole_DemotingVoter: // Voter -> DemotingVoter, only in joint state default: @@ -316,7 +316,7 @@ type promoteLearner struct { func (pl *promoteLearner) tick(engine *RaftEngine, region *core.RegionInfo) (newRegion *core.RegionInfo, isFinished bool) { isFinished = true peer := region.GetPeer(pl.peer.GetId()) - opts := checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_Learner, metapb.PeerRole_Voter) + opts := checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_Learner, metapb.PeerRole_Voter) if len(opts) > 0 { newRegion = region.Clone(opts...) } @@ -330,7 +330,7 @@ type demoteVoter struct { func (dv *demoteVoter) tick(engine *RaftEngine, region *core.RegionInfo) (newRegion *core.RegionInfo, isFinished bool) { isFinished = true peer := region.GetPeer(dv.peer.GetId()) - opts := checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_Voter, metapb.PeerRole_Learner) + opts := checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_Voter, metapb.PeerRole_Learner) if len(opts) > 0 { newRegion = region.Clone(opts...) } @@ -347,7 +347,7 @@ func (ce *changePeerV2Enter) tick(engine *RaftEngine, region *core.RegionInfo) ( var opts []core.RegionCreateOption for _, pl := range ce.promoteLearners { peer := region.GetPeer(pl.GetId()) - subOpts := checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_Learner, metapb.PeerRole_IncomingVoter) + subOpts := checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_Learner, metapb.PeerRole_IncomingVoter) if len(subOpts) == 0 { return } @@ -355,7 +355,7 @@ func (ce *changePeerV2Enter) tick(engine *RaftEngine, region *core.RegionInfo) ( } for _, dv := range ce.demoteVoters { peer := region.GetPeer(dv.GetId()) - subOpts := checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_Voter, metapb.PeerRole_DemotingVoter) + subOpts := checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_Voter, metapb.PeerRole_DemotingVoter) if len(subOpts) == 0 { return } @@ -373,9 +373,9 @@ func (cl *changePeerV2Leave) tick(engine *RaftEngine, region *core.RegionInfo) ( for _, peer := range region.GetPeers() { switch peer.GetRole() { case metapb.PeerRole_IncomingVoter: - opts = append(opts, checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_IncomingVoter, metapb.PeerRole_Voter)...) + opts = append(opts, checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_IncomingVoter, metapb.PeerRole_Voter)...) case metapb.PeerRole_DemotingVoter: - opts = append(opts, checkAndCreateChangePeerOption(engine, region, peer, metapb.PeerRole_DemotingVoter, metapb.PeerRole_Learner)...) + opts = append(opts, checkAndCreateChangePeerOption(region, peer, metapb.PeerRole_DemotingVoter, metapb.PeerRole_Learner)...) } } if len(opts) < 4 { @@ -408,9 +408,9 @@ func (a *addPeer) tick(engine *RaftEngine, region *core.RegionInfo) (newRegion * if region.GetPeer(a.peer.GetId()) == nil { switch a.peer.GetRole() { case metapb.PeerRole_Voter: - engine.schedulerStats.taskStats.incAddVoter(region.GetID()) + schedulingCounter.WithLabelValues("add-voter").Inc() case metapb.PeerRole_Learner: - engine.schedulerStats.taskStats.incAddLearner(region.GetID()) + schedulingCounter.WithLabelValues("add-learner").Inc() } pendingPeers := append(region.GetPendingPeers(), a.peer) return region.Clone(core.WithAddPeer(a.peer), core.WithIncConfVer(), core.WithPendingPeers(pendingPeers)), false @@ -419,11 +419,13 @@ func (a *addPeer) tick(engine *RaftEngine, region *core.RegionInfo) (newRegion * if !processSnapshot(sendNode, a.sendingStat) { return nil, false } - engine.schedulerStats.snapshotStats.incSendSnapshot(sendNode.Id) + sendStoreID := fmt.Sprintf("store-%d", sendNode.Id) + snapshotCounter.WithLabelValues(sendStoreID, "send").Inc() if !processSnapshot(recvNode, a.receivingStat) { return nil, false } - engine.schedulerStats.snapshotStats.incReceiveSnapshot(recvNode.Id) + recvStoreID := fmt.Sprintf("store-%d", recvNode.Id) + snapshotCounter.WithLabelValues(recvStoreID, "recv").Inc() recvNode.incUsedSize(uint64(region.GetApproximateSize())) // Step 3: Remove the Pending state newRegion = region.Clone(removePendingPeer(region, a.peer)) @@ -450,7 +452,7 @@ func (r *removePeer) tick(engine *RaftEngine, region *core.RegionInfo) (newRegio return nil, false } // Step 2: Remove Peer - engine.schedulerStats.taskStats.incRemovePeer(region.GetID()) + schedulingCounter.WithLabelValues("remove-peer").Inc() newRegion = region.Clone( core.WithIncConfVer(), core.WithRemoveStorePeer(r.peer.GetStoreId()),