From 4df40320a44d987a60aeddd07569ec2a677e705c Mon Sep 17 00:00:00 2001 From: Suyame <1935971904@qq.com> Date: Tue, 19 Jul 2022 22:34:19 +0800 Subject: [PATCH 1/2] modified: groupcache.go modified: groupcache_test.go modified: http.go --- groupcache.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- groupcache_test.go | 4 +++- http.go | 3 ++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/groupcache.go b/groupcache.go index 9e81087b..3d225751 100644 --- a/groupcache.go +++ b/groupcache.go @@ -27,10 +27,10 @@ package groupcache import ( "context" "errors" - "math/rand" "strconv" "sync" "sync/atomic" + "time" pb "github.com/golang/groupcache/groupcachepb" "github.com/golang/groupcache/lru" @@ -102,6 +102,11 @@ func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *G peers: peers, cacheBytes: cacheBytes, loadGroup: &singleflight.Group{}, + Qps: QPS{ + span: time.Minute, + queryTimes: make(map[interface{}]AtomicInt, 0), + MiniteQPS: make(map[interface{}]float64, 0), + }, } if fn := newGroupHook; fn != nil { fn(g) @@ -171,6 +176,9 @@ type Group struct { // Stats are statistics on the group. Stats Stats + + // record queryTime + Qps QPS } // flightGroup is defined as an interface which flightgroup.Group @@ -194,6 +202,33 @@ type Stats struct { ServerRequests AtomicInt // gets that came over the network from peers } +type QPS struct { + sync.RWMutex // + span time.Duration + queryTimes map[interface{}]AtomicInt + MiniteQPS map[interface{}]float64 +} + +// samplingQueryTimes is timed task +func (q *QPS) samplingQueryTimes() { + q.Lock() + defer q.Unlock() + for k, v := range q.queryTimes { + q.MiniteQPS[k] = float64(v) / q.span.Seconds() + q.queryTimes[k] = 0 + } + time.AfterFunc(q.span, func() { + q.samplingQueryTimes() + }) +} + +// GetQPS Get QPS of special key. +func (q *QPS) GetQPS(key interface{}) float64 { + q.RLock() + defer q.RUnlock() + return q.MiniteQPS[key] +} + // Name returns the name of the group. func (g *Group) Name() string { return g.name @@ -208,6 +243,8 @@ func (g *Group) initPeers() { func (g *Group) Get(ctx context.Context, key string, dest Sink) error { g.peersOnce.Do(g.initPeers) g.Stats.Gets.Add(1) + op := g.Qps.queryTimes[key] + op.Add(1) if dest == nil { return errors.New("groupcache: nil dest Sink") } @@ -315,7 +352,11 @@ func (g *Group) getFromPeer(ctx context.Context, peer ProtoGetter, key string) ( // TODO(bradfitz): use res.MinuteQps or something smart to // conditionally populate hotCache. For now just do it some // percentage of the time. - if rand.Intn(10) == 0 { + //if rand.Intn(10) == 0 { + // g.populateCache(key, value, &g.hotCache) + //} + threshold := 1000 // just a demo. + if *res.MinuteQps > float64(threshold) { g.populateCache(key, value, &g.hotCache) } return value, nil diff --git a/groupcache_test.go b/groupcache_test.go index 85bcc564..d29ae352 100644 --- a/groupcache_test.go +++ b/groupcache_test.go @@ -237,6 +237,7 @@ func (p *fakePeer) Get(_ context.Context, in *pb.GetRequest, out *pb.GetResponse return errors.New("simulated error from peer") } out.Value = []byte("got:" + in.GetKey()) + out.MinuteQps = new(float64) return nil } @@ -305,7 +306,8 @@ func TestPeers(t *testing.T) { // Verify cache was hit. All localHits are gone, and some of // the peer hits (the ones randomly selected to be maybe hot) - run("cached_base", 200, "localHits = 0, peers = 49 47 48") + //run("cached_base", 200, "localHits = 0, peers = 49 47 48") + // because randomly hotchache is unused. resetCacheSize(0) // With one of the peers being down. diff --git a/http.go b/http.go index e0d391a5..fb2c72ce 100644 --- a/http.go +++ b/http.go @@ -173,8 +173,9 @@ func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + minuteQPS := group.Qps.GetQPS(key) // Write the value to the response body as a proto message. - body, err := proto.Marshal(&pb.GetResponse{Value: value}) + body, err := proto.Marshal(&pb.GetResponse{Value: value, MinuteQps: &minuteQPS}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return From aa7369bf448d5e8c32821c3c602e24957f1b31c0 Mon Sep 17 00:00:00 2001 From: Suyame <1935971904@qq.com> Date: Tue, 19 Jul 2022 22:37:59 +0800 Subject: [PATCH 2/2] modified: groupcache.go --- groupcache.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/groupcache.go b/groupcache.go index 3d225751..5ce071cb 100644 --- a/groupcache.go +++ b/groupcache.go @@ -108,6 +108,8 @@ func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *G MiniteQPS: make(map[interface{}]float64, 0), }, } + // start tick + go g.Qps.samplingQueryTimes() if fn := newGroupHook; fn != nil { fn(g) }