diff --git a/pkg/mock/mockcluster/mockcluster.go b/pkg/mock/mockcluster/mockcluster.go index cbb8232614d..f26e3bcbda1 100644 --- a/pkg/mock/mockcluster/mockcluster.go +++ b/pkg/mock/mockcluster/mockcluster.go @@ -43,8 +43,7 @@ type Cluster struct { *core.BasicCluster *mockid.IDAllocator *placement.RuleManager - *statistics.HotCache - *statistics.StoresStats + *statistics.HotStat *config.PersistOptions ID uint64 suspectRegions map[uint64]struct{} @@ -56,8 +55,7 @@ func NewCluster(opts *config.PersistOptions) *Cluster { clus := &Cluster{ BasicCluster: core.NewBasicCluster(), IDAllocator: mockid.NewIDAllocator(), - HotCache: statistics.NewHotCache(), - StoresStats: statistics.NewStoresStats(), + HotStat: statistics.NewHotStat(), PersistOptions: opts, suspectRegions: map[uint64]struct{}{}, disabledFeatures: make(map[versioninfo.Feature]struct{}), @@ -92,7 +90,7 @@ func (mc *Cluster) LoadRegion(regionID uint64, followerIds ...uint64) { // GetStoresStats gets stores statistics. func (mc *Cluster) GetStoresStats() *statistics.StoresStats { - return mc.StoresStats + return mc.HotStat.StoresStats } // GetStoreRegionCount gets region count with a given store. diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 73b2219a64e..6b87674ef71 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -99,8 +99,7 @@ type RaftCluster struct { labelLevelStats *statistics.LabelStatistics regionStats *statistics.RegionStatistics - storesStats *statistics.StoresStats - hotSpotCache *statistics.HotCache + hotStat *statistics.HotStat coordinator *coordinator suspectRegions *cache.TTLUint64 // suspectRegions are regions that may need fix @@ -201,10 +200,9 @@ func (c *RaftCluster) InitCluster(id id.Allocator, opt *config.PersistOptions, s c.storage = storage c.id = id c.labelLevelStats = statistics.NewLabelStatistics() - c.storesStats = statistics.NewStoresStats() + c.hotStat = statistics.NewHotStat() c.prepareChecker = newPrepareChecker() c.changedRegions = make(chan *core.RegionInfo, defaultChangedRegionsLimit) - c.hotSpotCache = statistics.NewHotCache() c.suspectRegions = cache.NewIDTTL(c.ctx, time.Minute, 3*time.Minute) c.suspectKeyRanges = cache.NewStringTTL(c.ctx, time.Minute, 3*time.Minute) c.traceRegionFlow = opt.GetPDServerConfig().TraceRegionFlow @@ -297,7 +295,7 @@ func (c *RaftCluster) LoadClusterInfo() (*RaftCluster, error) { zap.Duration("cost", time.Since(start)), ) for _, store := range c.GetStores() { - c.storesStats.GetOrCreateRollingStoreStats(store.GetID()) + c.hotStat.GetOrCreateRollingStoreStats(store.GetID()) } return c, nil } @@ -520,13 +518,13 @@ func (c *RaftCluster) HandleStoreHeartbeat(stats *pdpb.StoreStats) error { } } if store := c.core.GetStore(newStore.GetID()); store != nil { - c.storesStats.UpdateStoreHeartbeatMetrics(store) + c.hotStat.UpdateStoreHeartbeatMetrics(store) } c.core.PutStore(newStore) - c.storesStats.Observe(newStore.GetID(), newStore.GetStoreStats()) - c.storesStats.UpdateTotalBytesRate(c.core.GetStores) - c.storesStats.UpdateTotalKeysRate(c.core.GetStores) - c.storesStats.FilterUnhealthyStore(c) + c.hotStat.Observe(newStore.GetID(), newStore.GetStoreStats()) + c.hotStat.UpdateTotalBytesRate(c.core.GetStores) + c.hotStat.UpdateTotalKeysRate(c.core.GetStores) + c.hotStat.FilterUnhealthyStore(c) // c.limiter is nil before "start" is called if c.limiter != nil && c.opt.GetStoreLimitMode() == "auto" { @@ -680,10 +678,10 @@ func (c *RaftCluster) processRegionHeartbeat(region *core.RegionInfo) error { } for _, writeItem := range writeItems { - c.hotSpotCache.Update(writeItem) + c.hotStat.Update(writeItem) } for _, readItem := range readItems { - c.hotSpotCache.Update(readItem) + c.hotStat.Update(readItem) } c.Unlock() @@ -801,7 +799,7 @@ func (c *RaftCluster) RandLearnerRegion(storeID uint64, ranges []core.KeyRange, func (c *RaftCluster) RandHotRegionFromStore(store uint64, kind statistics.FlowKind) *core.RegionInfo { c.RLock() defer c.RUnlock() - r := c.hotSpotCache.RandHotRegionFromStore(store, kind, c.opt.GetHotRegionCacheHitsThreshold()) + r := c.hotStat.RandHotRegionFromStore(store, kind, c.opt.GetHotRegionCacheHitsThreshold()) if r == nil { return nil } @@ -850,7 +848,7 @@ func (c *RaftCluster) GetRegionStats(startKey, endKey []byte) *statistics.Region func (c *RaftCluster) GetStoresStats() *statistics.StoresStats { c.RLock() defer c.RUnlock() - return c.storesStats + return c.hotStat.StoresStats } // DropCacheRegion removes a region from the cache. @@ -888,7 +886,7 @@ func (c *RaftCluster) GetStore(storeID uint64) *core.StoreInfo { func (c *RaftCluster) IsRegionHot(region *core.RegionInfo) bool { c.RLock() defer c.RUnlock() - return c.hotSpotCache.IsRegionHot(region, c.opt.GetHotRegionCacheHitsThreshold()) + return c.hotStat.IsRegionHot(region, c.opt.GetHotRegionCacheHitsThreshold()) } // GetAdjacentRegions returns regions' information that are adjacent with the specific region ID. @@ -1149,7 +1147,7 @@ func (c *RaftCluster) putStoreLocked(store *core.StoreInfo) error { } } c.core.PutStore(store) - c.storesStats.GetOrCreateRollingStoreStats(store.GetID()) + c.hotStat.GetOrCreateRollingStoreStats(store.GetID()) return nil } @@ -1226,7 +1224,7 @@ func (c *RaftCluster) deleteStoreLocked(store *core.StoreInfo) error { } } c.core.DeleteStore(store) - c.storesStats.RemoveRollingStoreStats(store.GetID()) + c.hotStat.RemoveRollingStoreStats(store.GetID()) return nil } @@ -1234,7 +1232,7 @@ func (c *RaftCluster) collectMetrics() { statsMap := statistics.NewStoreStatisticsMap(c.opt) stores := c.GetStores() for _, s := range stores { - statsMap.Observe(s, c.storesStats) + statsMap.Observe(s, c.hotStat.StoresStats) } statsMap.Collect() @@ -1264,7 +1262,7 @@ func (c *RaftCluster) collectClusterMetrics() { c.regionStats.Collect() c.labelLevelStats.Collect() // collect hot cache metrics - c.hotSpotCache.CollectMetrics() + c.hotStat.CollectMetrics() } func (c *RaftCluster) resetClusterMetrics() { @@ -1276,7 +1274,7 @@ func (c *RaftCluster) resetClusterMetrics() { c.regionStats.Reset() c.labelLevelStats.Reset() // reset hot cache metrics - c.hotSpotCache.ResetMetrics() + c.hotStat.ResetMetrics() } func (c *RaftCluster) collectHealthStatus() { @@ -1431,50 +1429,50 @@ func (c *RaftCluster) isPrepared() bool { func (c *RaftCluster) GetStoresBytesWriteStat() map[uint64]float64 { c.RLock() defer c.RUnlock() - return c.storesStats.GetStoresBytesWriteStat() + return c.hotStat.GetStoresBytesWriteStat() } // GetStoresBytesReadStat returns the bytes read stat of all StoreInfo. func (c *RaftCluster) GetStoresBytesReadStat() map[uint64]float64 { c.RLock() defer c.RUnlock() - return c.storesStats.GetStoresBytesReadStat() + return c.hotStat.GetStoresBytesReadStat() } // GetStoresKeysWriteStat returns the bytes write stat of all StoreInfo. func (c *RaftCluster) GetStoresKeysWriteStat() map[uint64]float64 { c.RLock() defer c.RUnlock() - return c.storesStats.GetStoresKeysWriteStat() + return c.hotStat.GetStoresKeysWriteStat() } // GetStoresKeysReadStat returns the bytes read stat of all StoreInfo. func (c *RaftCluster) GetStoresKeysReadStat() map[uint64]float64 { c.RLock() defer c.RUnlock() - return c.storesStats.GetStoresKeysReadStat() + return c.hotStat.GetStoresKeysReadStat() } // RegionReadStats returns hot region's read stats. func (c *RaftCluster) RegionReadStats() map[uint64][]*statistics.HotPeerStat { // RegionStats is a thread-safe method - return c.hotSpotCache.RegionStats(statistics.ReadFlow) + return c.hotStat.RegionStats(statistics.ReadFlow) } // RegionWriteStats returns hot region's write stats. func (c *RaftCluster) RegionWriteStats() map[uint64][]*statistics.HotPeerStat { // RegionStats is a thread-safe method - return c.hotSpotCache.RegionStats(statistics.WriteFlow) + return c.hotStat.RegionStats(statistics.WriteFlow) } // CheckWriteStatus checks the write status, returns whether need update statistics and item. func (c *RaftCluster) CheckWriteStatus(region *core.RegionInfo) []*statistics.HotPeerStat { - return c.hotSpotCache.CheckWrite(region) + return c.hotStat.CheckWrite(region) } // CheckReadStatus checks the read status, returns whether need update statistics and item. func (c *RaftCluster) CheckReadStatus(region *core.RegionInfo) []*statistics.HotPeerStat { - return c.hotSpotCache.CheckRead(region) + return c.hotStat.CheckRead(region) } // TODO: remove me. diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 55aef87d30d..e6ad71f28a4 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -108,7 +108,7 @@ func (s *testClusterInfoSuite) TestFilterUnhealthyStore(c *C) { } c.Assert(cluster.putStoreLocked(store), IsNil) c.Assert(cluster.HandleStoreHeartbeat(storeStats), IsNil) - c.Assert(cluster.storesStats.GetRollingStoreStats(store.GetID()), NotNil) + c.Assert(cluster.hotStat.GetRollingStoreStats(store.GetID()), NotNil) } for _, store := range stores { @@ -121,7 +121,7 @@ func (s *testClusterInfoSuite) TestFilterUnhealthyStore(c *C) { newStore := store.Clone(core.SetStoreState(metapb.StoreState_Tombstone)) c.Assert(cluster.putStoreLocked(newStore), IsNil) c.Assert(cluster.HandleStoreHeartbeat(storeStats), IsNil) - c.Assert(cluster.storesStats.GetRollingStoreStats(store.GetID()), IsNil) + c.Assert(cluster.hotStat.GetRollingStoreStats(store.GetID()), IsNil) } } diff --git a/server/statistics/hotstat.go b/server/statistics/hotstat.go new file mode 100644 index 00000000000..e122e5bf6a9 --- /dev/null +++ b/server/statistics/hotstat.go @@ -0,0 +1,28 @@ +// Copyright 2020 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package statistics + +// HotStat contains cluster's hotspot statistics. +type HotStat struct { + *HotCache + *StoresStats +} + +// NewHotStat creates the container to hold cluster's hotspot statistics. +func NewHotStat() *HotStat { + return &HotStat{ + HotCache: NewHotCache(), + StoresStats: NewStoresStats(), + } +}