Skip to content

Commit 31fceca

Browse files
authored
RedisCache: Use CollectedRequest (#3976)
* RedisCache: Use CollectedRequest Signed-off-by: Arve Knudsen <[email protected]> * RedisCache: Apply feedback from review Signed-off-by: Arve Knudsen <[email protected]> * Rename innerCtx to ctx Signed-off-by: Arve Knudsen <[email protected]> * Add changelog entry Signed-off-by: Arve Knudsen <[email protected]>
1 parent fdb1106 commit 31fceca

File tree

4 files changed

+58
-13
lines changed

4 files changed

+58
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## master / unreleased
44

5+
* [CHANGE] Added instrumentation to Redis client, with the following metrics: #3976
6+
- `rediscache_request_duration_seconds`
57
* [CHANGE] Enable strict JSON unmarshal for `pkg/util/validation.Limits` struct. The custom `UnmarshalJSON()` will now fail if the input has unknown fields. #4298
68
* [CHANGE] Cortex chunks storage has been deprecated and it's now in maintenance mode: all Cortex users are encouraged to migrate to the blocks storage. No new features will be added to the chunks storage. The default Cortex configuration still runs the chunks engine; please check out the [blocks storage doc](https://cortexmetrics.io/docs/blocks-storage/) on how to configure Cortex to run with the blocks storage. #4268
79
* [CHANGE] The example Kubernetes manifests (stored at `k8s/`) have been removed due to a lack of proper support and maintenance. #4268

pkg/chunk/cache/cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error
9999
cfg.Redis.Expiration = cfg.DefaultValidity
100100
}
101101
cacheName := cfg.Prefix + "redis"
102-
cache := NewRedisCache(cacheName, NewRedisClient(&cfg.Redis), logger)
102+
cache := NewRedisCache(cacheName, NewRedisClient(&cfg.Redis), reg, logger)
103103
caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg))
104104
}
105105

pkg/chunk/cache/redis_cache.go

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,91 @@ import (
55

66
"github.com/go-kit/kit/log"
77
"github.com/go-kit/kit/log/level"
8+
otlog "github.com/opentracing/opentracing-go/log"
9+
"github.com/prometheus/client_golang/prometheus"
10+
"github.com/prometheus/client_golang/prometheus/promauto"
11+
instr "github.com/weaveworks/common/instrument"
812

913
util_log "github.com/cortexproject/cortex/pkg/util/log"
14+
"github.com/cortexproject/cortex/pkg/util/spanlogger"
1015
)
1116

1217
// RedisCache type caches chunks in redis
1318
type RedisCache struct {
14-
name string
15-
redis *RedisClient
16-
logger log.Logger
19+
name string
20+
redis *RedisClient
21+
logger log.Logger
22+
requestDuration observableVecCollector
1723
}
1824

1925
// NewRedisCache creates a new RedisCache
20-
func NewRedisCache(name string, redisClient *RedisClient, logger log.Logger) *RedisCache {
26+
func NewRedisCache(name string, redisClient *RedisClient, reg prometheus.Registerer, logger log.Logger) *RedisCache {
2127
util_log.WarnExperimentalUse("Redis cache")
2228
cache := &RedisCache{
2329
name: name,
2430
redis: redisClient,
2531
logger: logger,
32+
requestDuration: observableVecCollector{
33+
v: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
34+
Namespace: "cortex",
35+
Name: "rediscache_request_duration_seconds",
36+
Help: "Total time spent in seconds doing Redis requests.",
37+
Buckets: prometheus.ExponentialBuckets(0.000016, 4, 8),
38+
ConstLabels: prometheus.Labels{"name": name},
39+
}, []string{"method", "status_code"}),
40+
},
2641
}
2742
if err := cache.redis.Ping(context.Background()); err != nil {
2843
level.Error(logger).Log("msg", "error connecting to redis", "name", name, "err", err)
2944
}
3045
return cache
3146
}
3247

48+
func redisStatusCode(err error) string {
49+
// TODO: Figure out if there are more error types returned by Redis
50+
switch err {
51+
case nil:
52+
return "200"
53+
default:
54+
return "500"
55+
}
56+
}
57+
3358
// Fetch gets keys from the cache. The keys that are found must be in the order of the keys requested.
3459
func (c *RedisCache) Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missed []string) {
35-
data, err := c.redis.MGet(ctx, keys)
60+
const method = "RedisCache.MGet"
61+
var items [][]byte
62+
// Run a tracked request, using c.requestDuration to monitor requests.
63+
err := instr.CollectedRequest(ctx, method, c.requestDuration, redisStatusCode, func(ctx context.Context) error {
64+
log, _ := spanlogger.New(ctx, method)
65+
defer log.Finish()
66+
log.LogFields(otlog.Int("keys requested", len(keys)))
67+
68+
var err error
69+
items, err = c.redis.MGet(ctx, keys)
70+
if err != nil {
71+
log.Error(err)
72+
level.Error(c.logger).Log("msg", "failed to get from redis", "name", c.name, "err", err)
73+
return err
74+
}
75+
76+
log.LogFields(otlog.Int("keys found", len(items)))
77+
78+
return nil
79+
})
3680
if err != nil {
37-
level.Error(c.logger).Log("msg", "failed to get from redis", "name", c.name, "err", err)
38-
missed = make([]string, len(keys))
39-
copy(missed, keys)
40-
return
81+
return found, bufs, keys
4182
}
83+
4284
for i, key := range keys {
43-
if data[i] != nil {
85+
if items[i] != nil {
4486
found = append(found, key)
45-
bufs = append(bufs, data[i])
87+
bufs = append(bufs, items[i])
4688
} else {
4789
missed = append(missed, key)
4890
}
4991
}
92+
5093
return
5194
}
5295

pkg/chunk/cache/redis_cache_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ func mockRedisCache() (*RedisCache, error) {
6363
Addrs: []string{redisServer.Addr()},
6464
}),
6565
}
66-
return NewRedisCache("mock", redisClient, log.NewNopLogger()), nil
66+
return NewRedisCache("mock", redisClient, nil, log.NewNopLogger()), nil
6767
}

0 commit comments

Comments
 (0)