diff --git a/server/statistics/hot_cache.go b/server/statistics/hot_cache.go index 17cd9b33cf4..259f0c7944d 100644 --- a/server/statistics/hot_cache.go +++ b/server/statistics/hot_cache.go @@ -46,7 +46,7 @@ func NewHotCache(ctx context.Context) *HotCache { return w } -// ExpiredItems returns the items which are already expired. +// ExpiredItems returns the items which are already expired.: func (w *HotCache) ExpiredItems(region *core.RegionInfo) (expiredItems []*HotPeerStat) { expiredItems = append(expiredItems, w.writeFlow.ExpiredItems(region)...) expiredItems = append(expiredItems, w.readFlow.ExpiredItems(region)...) diff --git a/server/statistics/hot_peer_cache.go b/server/statistics/hot_peer_cache.go index 5726d88de28..14e9da12784 100644 --- a/server/statistics/hot_peer_cache.go +++ b/server/statistics/hot_peer_cache.go @@ -33,7 +33,6 @@ const ( // WriteReportInterval indicates the interval between write interval WriteReportInterval = RegionHeartBeatReportInterval // ReadReportInterval indicates the interval between read stats report - // TODO: use StoreHeartBeatReportInterval in future ReadReportInterval = StoreHeartBeatReportInterval rollingWindowsSize = 5 @@ -208,7 +207,7 @@ func (f *hotPeerCache) CheckPeerFlow(peer *core.PeerInfo, region *core.RegionInf loads[i] = deltaLoads[i] / float64(interval) } justTransferLeader := f.justTransferLeader(region) - // transfer read leader or remove write peer + // remove peer isExpired := f.isPeerExpired(peer, region) oldItem := f.getOldHotPeerStat(region.GetID(), storeID) if isExpired && oldItem != nil { @@ -284,14 +283,7 @@ func (f *hotPeerCache) getOldHotPeerStat(regionID, storeID uint64) *HotPeerStat func (f *hotPeerCache) isPeerExpired(peer *core.PeerInfo, region *core.RegionInfo) bool { storeID := peer.GetStoreID() - switch f.kind { - case WriteFlow: - return region.GetStorePeer(storeID) == nil - //TODO: make readFlow isPeerExpired condition as same as the writeFlow - case ReadFlow: - return region.GetLeader().GetStoreId() != storeID - } - return false + return region.GetStorePeer(storeID) == nil } func (f *hotPeerCache) calcHotThresholds(storeID uint64) []float64 { @@ -444,6 +436,8 @@ func (f *hotPeerCache) updateHotPeerStat(newItem, oldItem *HotPeerStat, deltaLoa newItem.lastTransferLeaderTime = time.Now() // skip the first heartbeat flow statistic after transfer leader, because its statistics are calculated by the last leader in this store and are inaccurate // maintain anticount and hotdegree to avoid store threshold and hot peer are unstable. + // For write stat, as the stat is send by region heartbeat, the first heartbeat will be skipped. + // For read stat, as the stat is send by store heartbeat, the first heartbeat won't be skipped. if newItem.Kind == WriteFlow { newItem.HotDegree = oldItem.HotDegree newItem.AntiCount = oldItem.AntiCount diff --git a/server/statistics/hot_peer_cache_test.go b/server/statistics/hot_peer_cache_test.go index 8682ee18a47..d2232649fe0 100644 --- a/server/statistics/hot_peer_cache_test.go +++ b/server/statistics/hot_peer_cache_test.go @@ -67,19 +67,19 @@ const ( ) type testCacheCase struct { - kind FlowKind - operator operator - expect int + kind FlowKind + operator operator + expect int + needDelete bool } func (t *testHotPeerCache) TestCache(c *C) { tests := []*testCacheCase{ - {ReadFlow, transferLeader, 2}, - {ReadFlow, movePeer, 1}, - {ReadFlow, addReplica, 1}, - {WriteFlow, transferLeader, 3}, - {WriteFlow, movePeer, 4}, - {WriteFlow, addReplica, 4}, + {ReadFlow, movePeer, 1, false}, + {ReadFlow, addReplica, 1, true}, + {WriteFlow, transferLeader, 3, true}, + {WriteFlow, movePeer, 4, true}, + {WriteFlow, addReplica, 4, true}, } for _, t := range tests { testCache(c, t) @@ -100,7 +100,7 @@ func testCache(c *C, t *testCacheCase) { res := checkAndUpdate(c, cache, region, t.expect) checkHit(c, cache, region, t.kind, true) // hit cache if t.expect != defaultSize[t.kind] { - checkNeedDelete(c, res, srcStore) + checkNeedDelete(c, res, srcStore, t.needDelete) } } @@ -127,10 +127,10 @@ func checkHit(c *C, cache *hotPeerCache, region *core.RegionInfo, kind FlowKind, } } -func checkNeedDelete(c *C, ret []*HotPeerStat, storeID uint64) { +func checkNeedDelete(c *C, ret []*HotPeerStat, storeID uint64, needDelete bool) { for _, item := range ret { if item.StoreID == storeID { - c.Assert(item.needDelete, IsTrue) + c.Assert(item.needDelete, Equals, needDelete) return } }