From 9eb4ada1c7ec0934941d45f2dd4a2f21dae06199 Mon Sep 17 00:00:00 2001 From: zhangkun <> Date: Thu, 10 Feb 2022 19:37:20 +0800 Subject: [PATCH] avoid cache avalanche At the beginning of client start, there is no table region info in cache. If there are many go routine to access a table at same time, they will miss cache and send request package to get table region info. In this case, too many duplicated requests should be avoid. --- client.go | 4 ++++ rpc.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/client.go b/client.go index 982ddb27..52adf57b 100644 --- a/client.go +++ b/client.go @@ -97,6 +97,10 @@ type client struct { string, time.Duration, compression.Codec) hrpc.RegionClient compressionCodec compression.Codec + + + // region looker lock container + regionLookerMap sync.Map } // NewClient creates a new HBase client. diff --git a/rpc.go b/rpc.go index 32875ac1..d7f2e9ee 100644 --- a/rpc.go +++ b/rpc.go @@ -12,6 +12,7 @@ import ( "fmt" "io" "strconv" + "sync" "time" "github.com/prometheus/client_golang/prometheus" @@ -54,6 +55,17 @@ const ( ) func (c *client) getRegionForRpc(rpc hrpc.Call) (hrpc.RegionInfo, error) { + // Check the cache for a region that can handle this request + // if in cache, return quickly + if reg := c.getRegionFromCache(rpc.Table(), rpc.Key()); reg != nil { + return reg, nil + } + + il, _ := c.regionLookerMap.LoadOrStore(string(rpc.Table()), &sync.Mutex{}) + lo := il.(*sync.Mutex) + lo.Lock() + defer lo.Unlock() + for i := 0; i < maxFindRegionTries; i++ { // Check the cache for a region that can handle this request if reg := c.getRegionFromCache(rpc.Table(), rpc.Key()); reg != nil {