Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.

Commit 4f37671

Browse files
committed
Replace remaining uses of bigcache with clockcache
Bigcache is a TTL cache, making it largely inappropriate for our use case where the cache is mainly a garbage collection mechanism for dead metrics and series, both of which we expect to change in a time-correlated fashion. This commit switches the remaining usages to our own clockcache, whose eviction policy we expect to be better suited to our usage. Right now the cache sizes are constants. It may be worth keeping a hit-rate for each cache so we can start off with a smaller initial size and grow the caches if the miss-rate is too large.
1 parent b82424d commit 4f37671

File tree

8 files changed

+90
-126
lines changed

8 files changed

+90
-126
lines changed

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ go 1.14
55
require (
66
github.com/NYTimes/gziphandler v1.1.1
77
github.com/OneOfOne/xxhash v1.2.5 // indirect
8-
github.com/allegro/bigcache v1.2.1
98
github.com/blang/semver/v4 v4.0.0
109
github.com/docker/go-connections v0.4.0
1110
github.com/edsrzf/mmap-go v1.0.0

go.sum

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
7373
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
7474
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
7575
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
76-
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
77-
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
7876
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
7977
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
8078
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
@@ -419,6 +417,7 @@ github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9
419417
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
420418
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
421419
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
420+
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
422421
github.com/jackc/pgerrcode v0.0.0-20190803225404-afa3381909a6 h1:geJ1mgTGd0WQo67wEd+H4OjFG5uA2e3cEBz9D5+pftU=
423422
github.com/jackc/pgerrcode v0.0.0-20190803225404-afa3381909a6/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
424423
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=

pkg/log/log.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,6 @@ func Fatal(keyvals ...interface{}) {
6969
os.Exit(1)
7070
}
7171

72-
// CustomCacheLogger is a custom logger used for transforming cache logs
73-
// so that they conform the our logging setup. It also implements the
74-
// bigcache.Logger interface.
75-
type CustomCacheLogger struct{}
76-
77-
// Printf sends the log in the debug stream of the logger.
78-
func (c *CustomCacheLogger) Printf(format string, v ...interface{}) {
79-
_ = level.Debug(logger).Log("msg", fmt.Sprintf(format, v...))
80-
}
81-
8272
func parseLogLevel(logLevel string) (level.Option, error) {
8373
switch logLevel {
8474
case "debug":

pkg/pgclient/client.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88

99
"github.com/prometheus/client_golang/prometheus"
1010

11-
"github.com/allegro/bigcache"
1211
"github.com/jackc/pgx/v4/pgxpool"
1312

13+
"github.com/timescale/timescale-prometheus/pkg/clockcache"
1414
"github.com/timescale/timescale-prometheus/pkg/prompb"
1515

1616
"github.com/timescale/timescale-prometheus/pkg/log"
@@ -31,6 +31,8 @@ type Config struct {
3131
AsyncAcks bool
3232
ReportInterval int
3333
LabelsCacheSize uint64
34+
MetricsCacheSize uint64
35+
SeriesCacheSize uint64
3436
}
3537

3638
// ParseFlags parses the configuration flags specific to PostgreSQL and TimescaleDB
@@ -45,6 +47,8 @@ func ParseFlags(cfg *Config) *Config {
4547
flag.BoolVar(&cfg.AsyncAcks, "async-acks", false, "Ack before data is written to DB")
4648
flag.IntVar(&cfg.ReportInterval, "tput-report", 0, "interval in seconds at which throughput should be reported")
4749
flag.Uint64Var(&cfg.LabelsCacheSize, "labels-cache-size", 10000, "maximum number of labels to cache")
50+
flag.Uint64Var(&cfg.MetricsCacheSize, "metrics-cache-size", pgmodel.DefaultMetricCacheSize, "maximum number of metric names to cache")
51+
flag.Uint64Var(&cfg.SeriesCacheSize, "series-cache-size", pgmodel.DefaultSeriesCacheSize, "maximum number of series-sets to cache")
4852
return cfg
4953
}
5054

@@ -78,10 +82,13 @@ func NewClient(cfg *Config, readHist prometheus.ObserverVec) (*Client, error) {
7882
return nil, err
7983
}
8084

81-
metrics, _ := bigcache.NewBigCache(pgmodel.DefaultCacheConfig())
82-
cache := &pgmodel.MetricNameCache{Metrics: metrics}
85+
cache := &pgmodel.MetricNameCache{Metrics: clockcache.WithMax(cfg.MetricsCacheSize)}
8386

84-
c := pgmodel.Cfg{AsyncAcks: cfg.AsyncAcks, ReportInterval: cfg.ReportInterval}
87+
c := pgmodel.Cfg{
88+
AsyncAcks: cfg.AsyncAcks,
89+
ReportInterval: cfg.ReportInterval,
90+
SeriesCacheSize: cfg.SeriesCacheSize,
91+
}
8592
ingestor, err := pgmodel.NewPgxIngestorWithMetricCache(connectionPool, cache, &c)
8693
if err != nil {
8794
log.Error("err starting ingestor", err)

pkg/pgmodel/bigcache.go

Lines changed: 0 additions & 80 deletions
This file was deleted.

pkg/pgmodel/cache.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// This file and its contents are licensed under the Apache License 2.0.
2+
// Please see the included NOTICE for copyright information and
3+
// LICENSE for a copy of the license.
4+
5+
package pgmodel
6+
7+
import (
8+
"fmt"
9+
"strings"
10+
11+
"github.com/timescale/timescale-prometheus/pkg/clockcache"
12+
)
13+
14+
const (
15+
DefaultMetricCacheSize = 10000
16+
DefaultSeriesCacheSize = 100000
17+
)
18+
19+
var (
20+
// ErrEntryNotFound is returned when entry is not found.
21+
ErrEntryNotFound = fmt.Errorf("entry not found")
22+
)
23+
24+
type seriesCache struct {
25+
series *clockcache.Cache
26+
}
27+
28+
func (b *seriesCache) GetSeries(lset Labels) (SeriesID, error) {
29+
result, ok := b.series.Get(lset.String())
30+
if !ok {
31+
return 0, ErrEntryNotFound
32+
}
33+
return result.(SeriesID), nil
34+
}
35+
36+
func (b *seriesCache) SetSeries(lset Labels, id SeriesID) error {
37+
b.series.Insert(lset.String(), id)
38+
return nil
39+
}
40+
41+
// MetricNameCache stores and retrieves metric table names in a in-memory cache.
42+
type MetricNameCache struct {
43+
Metrics *clockcache.Cache
44+
}
45+
46+
// Get fetches the table name for specified metric.
47+
func (m *MetricNameCache) Get(metric string) (string, error) {
48+
result, ok := m.Metrics.Get(metric)
49+
if !ok {
50+
return "", ErrEntryNotFound
51+
}
52+
return result.(string), nil
53+
}
54+
55+
// Set stores table name for specified metric.
56+
func (m *MetricNameCache) Set(metric string, tableName string) error {
57+
// deep copy the strings so the original memory doesn't need to stick around
58+
metricBuilder := strings.Builder{}
59+
metricBuilder.Grow(len(metric))
60+
metricBuilder.WriteString(metric)
61+
tableBuilder := strings.Builder{}
62+
tableBuilder.Grow(len(tableName))
63+
tableBuilder.WriteString(tableName)
64+
m.Metrics.Insert(metricBuilder.String(), tableBuilder.String())
65+
return nil
66+
}

pkg/pgmodel/bigcache_test.go renamed to pkg/pgmodel/cache_test.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@ import (
77
"math"
88
"strings"
99
"testing"
10-
"time"
1110

12-
"github.com/allegro/bigcache"
1311
"github.com/prometheus/prometheus/pkg/labels"
12+
"github.com/timescale/timescale-prometheus/pkg/clockcache"
1413
)
1514

16-
func TestBigCache(t *testing.T) {
17-
config := bigcache.DefaultConfig(10 * time.Minute)
18-
series, err := bigcache.NewBigCache(config)
19-
if err != nil {
20-
t.Fatal("unable to run test, unable to create labels cache")
21-
}
22-
cache := bCache{
23-
series: series,
15+
func TestCache(t *testing.T) {
16+
cache := seriesCache{
17+
series: clockcache.WithMax(100),
2418
}
2519

2620
label := labels.Labels{
@@ -145,17 +139,11 @@ func TestMetricTableNameCache(t *testing.T) {
145139
tableName: "",
146140
},
147141
}
148-
config := bigcache.DefaultConfig(10 * time.Minute)
149142

150143
for _, c := range testCases {
151144
t.Run(c.name, func(t *testing.T) {
152-
metrics, err := bigcache.NewBigCache(config)
153-
154-
if err != nil {
155-
t.Fatal("unable to run test, unable to create metrics table name cache")
156-
}
157145
cache := MetricNameCache{
158-
Metrics: metrics,
146+
Metrics: clockcache.WithMax(100),
159147
}
160148

161149
missing, err := cache.Get(c.metric)

pkg/pgmodel/pgx.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"sync/atomic"
1616
"time"
1717

18-
"github.com/allegro/bigcache"
1918
"github.com/jackc/pgconn"
2019
"github.com/jackc/pgerrcode"
2120
"github.com/jackc/pgx/v4"
@@ -189,8 +188,9 @@ func (t *SampleInfoIterator) Err() error {
189188
}
190189

191190
type Cfg struct {
192-
AsyncAcks bool
193-
ReportInterval int
191+
AsyncAcks bool
192+
ReportInterval int
193+
SeriesCacheSize uint64
194194
}
195195

196196
// NewPgxIngestorWithMetricCache returns a new Ingestor that uses connection pool and a metrics cache
@@ -206,11 +206,7 @@ func NewPgxIngestorWithMetricCache(c *pgxpool.Pool, cache MetricCache, cfg *Cfg)
206206
return nil, err
207207
}
208208

209-
series, _ := bigcache.NewBigCache(DefaultCacheConfig())
210-
211-
bc := &bCache{
212-
series: series,
213-
}
209+
bc := &seriesCache{clockcache.WithMax(cfg.SeriesCacheSize)}
214210

215211
return &DBIngestor{
216212
db: pi,
@@ -220,8 +216,8 @@ func NewPgxIngestorWithMetricCache(c *pgxpool.Pool, cache MetricCache, cfg *Cfg)
220216

221217
// NewPgxIngestor returns a new Ingestor that write to PostgreSQL using PGX
222218
func NewPgxIngestor(c *pgxpool.Pool) (*DBIngestor, error) {
223-
metrics, _ := bigcache.NewBigCache(DefaultCacheConfig())
224-
cache := &MetricNameCache{metrics}
219+
//TODO what size should we use?
220+
cache := &MetricNameCache{clockcache.WithMax(DefaultMetricCacheSize)}
225221
return NewPgxIngestorWithMetricCache(c, cache, &Cfg{})
226222
}
227223

@@ -900,8 +896,7 @@ func NewPgxReaderWithMetricCache(c *pgxpool.Pool, cache MetricCache, labelsCache
900896

901897
// NewPgxReader returns a new DBReader that reads that from PostgreSQL using PGX.
902898
func NewPgxReader(c *pgxpool.Pool, readHist prometheus.ObserverVec, labelsCacheSize uint64) *DBReader {
903-
metrics, _ := bigcache.NewBigCache(DefaultCacheConfig())
904-
cache := &MetricNameCache{metrics}
899+
cache := &MetricNameCache{clockcache.WithMax(DefaultMetricCacheSize)}
905900
return NewPgxReaderWithMetricCache(c, cache, labelsCacheSize)
906901
}
907902

0 commit comments

Comments
 (0)