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

Commit 462489e

Browse files
committed
Add counters for the various cache sizes
Add prometheus counters for the number of elements stored int the various caches we have. This should help us debug cache-sizing issues, should any occur.
1 parent 4f37671 commit 462489e

File tree

11 files changed

+176
-6
lines changed

11 files changed

+176
-6
lines changed

cmd/timescale-prometheus/main.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import (
1010
"context"
1111
"flag"
1212
"fmt"
13-
"github.com/prometheus/common/route"
1413
"net/http"
1514
_ "net/http/pprof"
1615
"os"
1716
"sync/atomic"
1817
"time"
1918

19+
"github.com/prometheus/common/route"
20+
2021
"github.com/jackc/pgx/v4/pgxpool"
2122
_ "github.com/jackc/pgx/v4/stdlib"
2223

@@ -194,6 +195,61 @@ func main() {
194195
}
195196
defer client.Close()
196197

198+
cachedMetricNames := prometheus.NewCounterFunc(prometheus.CounterOpts{
199+
Namespace: promNamespace,
200+
Name: "metric_name_cache_elements_stored",
201+
Help: "Total number of metric names in the metric name cache.",
202+
}, func() float64 {
203+
return float64(client.NumCachedMetricNames())
204+
})
205+
206+
metricNamesCacheCap := prometheus.NewGaugeFunc(prometheus.GaugeOpts{
207+
Namespace: promNamespace,
208+
Name: "metric_name_cache_capacity",
209+
Help: "Maximum number of elements in the metric names cache.",
210+
}, func() float64 {
211+
return float64(client.MetricNamesCacheCapacity())
212+
})
213+
214+
cachedSeriesSets := prometheus.NewCounterFunc(prometheus.CounterOpts{
215+
Namespace: promNamespace,
216+
Name: "series_set_cache_elements_stored",
217+
Help: "Total number of labels to series-set id mappings cached.",
218+
}, func() float64 {
219+
return float64(client.NumCachedSeries())
220+
})
221+
222+
seriesSetCacheCap := prometheus.NewGaugeFunc(prometheus.GaugeOpts{
223+
Namespace: promNamespace,
224+
Name: "series_set_cache_capacity",
225+
Help: "Maximum number of elements in the series-set cache.",
226+
}, func() float64 {
227+
return float64(client.SeriesCacheCapacity())
228+
})
229+
230+
cachedLabels := prometheus.NewCounterFunc(prometheus.CounterOpts{
231+
Namespace: promNamespace,
232+
Name: "label_cache_elements_stored",
233+
Help: "Total number of label-id to label mappings cache.",
234+
}, func() float64 {
235+
return float64(client.NumCachedLabels())
236+
})
237+
238+
labelsCacheCap := prometheus.NewGaugeFunc(prometheus.GaugeOpts{
239+
Namespace: promNamespace,
240+
Name: "label_cache_capacity",
241+
Help: "Total number of label-id to label mappings cache.",
242+
}, func() float64 {
243+
return float64(client.LabelsCacheCapacity())
244+
})
245+
246+
prometheus.MustRegister(cachedMetricNames)
247+
prometheus.MustRegister(metricNamesCacheCap)
248+
prometheus.MustRegister(cachedSeriesSets)
249+
prometheus.MustRegister(seriesSetCacheCap)
250+
prometheus.MustRegister(cachedLabels)
251+
prometheus.MustRegister(labelsCacheCap)
252+
197253
router := route.New()
198254

199255
promMetrics := api.Metrics{
@@ -207,6 +263,9 @@ func main() {
207263
QueryBatchDuration: queryBatchDuration,
208264
FailedQueries: failedQueries,
209265
ReceivedQueries: receivedQueries,
266+
CachedMetricNames: cachedMetricNames,
267+
CachedSeriesSets: cachedSeriesSets,
268+
CachedLabels: cachedLabels,
210269
}
211270
writeHandler := timeHandler(httpRequestDuration, "write", api.Write(client, elector, &promMetrics))
212271
router.Post("/write", writeHandler)

pkg/api/metrics.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ type Metrics struct {
1818
ReceivedQueries prometheus.Counter
1919
FailedQueries prometheus.Counter
2020
QueryBatchDuration prometheus.Histogram
21+
CachedMetricNames prometheus.CounterFunc
22+
CachedSeriesSets prometheus.CounterFunc
23+
CachedLabels prometheus.CounterFunc
2124
}

pkg/api/query_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/prometheus/prometheus/promql/parser"
1717
"github.com/prometheus/prometheus/storage"
1818
"github.com/timescale/timescale-prometheus/pkg/log"
19+
"github.com/timescale/timescale-prometheus/pkg/pgmodel"
1920
"github.com/timescale/timescale-prometheus/pkg/prompb"
2021
"github.com/timescale/timescale-prometheus/pkg/promql"
2122
"github.com/timescale/timescale-prometheus/pkg/query"
@@ -42,6 +43,8 @@ type mockQuerier struct {
4243
labelNamesErr error
4344
}
4445

46+
var _ pgmodel.Querier = (*mockQuerier)(nil)
47+
4548
func (m mockQuerier) LabelNames() ([]string, error) {
4649
return m.labelNames, m.labelNamesErr
4750
}
@@ -60,6 +63,14 @@ func (m mockQuerier) Select(int64, int64, bool, *storage.SelectHints, []parser.N
6063
return &mockSeriesSet{}, nil, nil, m.selectErr
6164
}
6265

66+
func (m mockQuerier) NumCachedLabels() int {
67+
return 0
68+
}
69+
70+
func (m mockQuerier) LabelsCacheCapacity() int {
71+
return 0
72+
}
73+
6374
func TestParseDuration(t *testing.T) {
6475
testCase := []struct {
6576
in string

pkg/clockcache/cache.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ func (self *Cache) Len() int {
273273
return len(self.storage)
274274
}
275275

276+
func (self *Cache) Cap() int {
277+
self.elementsLock.RLock()
278+
defer self.elementsLock.RUnlock()
279+
return cap(self.storage)
280+
}
281+
276282
func (self *Cache) debugString() string {
277283
self.elementsLock.RLock()
278284
defer self.elementsLock.RUnlock()

pkg/pgclient/client.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ type Client struct {
6060
queryable *query.Queryable
6161
cfg *Config
6262
ConnectionStr string
63+
metricCache *pgmodel.MetricNameCache
6364
}
6465

6566
// NewClient creates a new PostgreSQL client
@@ -98,7 +99,14 @@ func NewClient(cfg *Config, readHist prometheus.ObserverVec) (*Client, error) {
9899

99100
queryable := query.NewQueryable(reader.GetQuerier())
100101

101-
return &Client{Connection: connectionPool, ingestor: ingestor, reader: reader, queryable: queryable, cfg: cfg}, nil
102+
return &Client{
103+
Connection: connectionPool,
104+
ingestor: ingestor,
105+
reader: reader,
106+
queryable: queryable,
107+
cfg: cfg,
108+
metricCache: cache,
109+
}, nil
102110
}
103111

104112
// GetConnectionStr returns a Postgres connection string
@@ -122,6 +130,30 @@ func (c *Client) Read(req *prompb.ReadRequest) (*prompb.ReadResponse, error) {
122130
return c.reader.Read(req)
123131
}
124132

133+
func (c *Client) NumCachedSeries() int {
134+
return c.ingestor.NumCachedSeries()
135+
}
136+
137+
func (c *Client) SeriesCacheCapacity() int {
138+
return c.ingestor.SeriesCacheCapacity()
139+
}
140+
141+
func (c *Client) NumCachedMetricNames() int {
142+
return c.metricCache.NumElements()
143+
}
144+
145+
func (c *Client) MetricNamesCacheCapacity() int {
146+
return c.metricCache.Capacity()
147+
}
148+
149+
func (c *Client) NumCachedLabels() int {
150+
return c.reader.GetQuerier().NumCachedLabels()
151+
}
152+
153+
func (c *Client) LabelsCacheCapacity() int {
154+
return c.reader.GetQuerier().LabelsCacheCapacity()
155+
}
156+
125157
// HealthCheck checks that the client is properly connected
126158
func (c *Client) HealthCheck() error {
127159
return c.reader.HealthCheck()

pkg/pgmodel/cache.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type seriesCache struct {
2525
series *clockcache.Cache
2626
}
2727

28+
var _ SeriesCache = (*seriesCache)(nil)
29+
2830
func (b *seriesCache) GetSeries(lset Labels) (SeriesID, error) {
2931
result, ok := b.series.Get(lset.String())
3032
if !ok {
@@ -38,6 +40,14 @@ func (b *seriesCache) SetSeries(lset Labels, id SeriesID) error {
3840
return nil
3941
}
4042

43+
func (b *seriesCache) NumElements() int {
44+
return b.series.Len()
45+
}
46+
47+
func (b *seriesCache) Capacity() int {
48+
return b.series.Cap()
49+
}
50+
4151
// MetricNameCache stores and retrieves metric table names in a in-memory cache.
4252
type MetricNameCache struct {
4353
Metrics *clockcache.Cache
@@ -64,3 +74,11 @@ func (m *MetricNameCache) Set(metric string, tableName string) error {
6474
m.Metrics.Insert(metricBuilder.String(), tableBuilder.String())
6575
return nil
6676
}
77+
78+
func (m *MetricNameCache) NumElements() int {
79+
return m.Metrics.Len()
80+
}
81+
82+
func (m *MetricNameCache) Capacity() int {
83+
return m.Metrics.Cap()
84+
}

pkg/pgmodel/ingestor.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ type seriesWithCallback struct {
3434
Callback func(l Labels, id SeriesID) error
3535
}
3636

37-
// Cache provides a caching mechanism for labels and series.
38-
type Cache interface {
37+
// SeriesCache provides a caching mechanism for labels and series.
38+
type SeriesCache interface {
3939
GetSeries(lset Labels) (SeriesID, error)
4040
SetSeries(lset Labels, id SeriesID) error
41+
NumElements() int
42+
Capacity() int
4143
}
4244

4345
type samplesInfo struct {
@@ -48,7 +50,7 @@ type samplesInfo struct {
4850

4951
// DBIngestor ingest the TimeSeries data into Timescale database.
5052
type DBIngestor struct {
51-
cache Cache
53+
cache SeriesCache
5254
db inserter
5355
}
5456

@@ -105,6 +107,14 @@ func (i *DBIngestor) parseData(tts []prompb.TimeSeries, req *prompb.WriteRequest
105107
return dataSamples, rows, nil
106108
}
107109

110+
func (i *DBIngestor) NumCachedSeries() int {
111+
return i.cache.NumElements()
112+
}
113+
114+
func (i *DBIngestor) SeriesCacheCapacity() int {
115+
return i.cache.Capacity()
116+
}
117+
108118
// Close closes the ingestor
109119
func (i *DBIngestor) Close() {
110120
i.db.Close()

pkg/pgmodel/ingestor_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ type mockCache struct {
1616
setSeriesErr error
1717
}
1818

19+
var _ SeriesCache = (*mockCache)(nil)
20+
1921
func (m *mockCache) GetSeries(lset Labels) (SeriesID, error) {
2022
if m.getSeriesErr != nil {
2123
return 0, m.getSeriesErr
@@ -34,6 +36,14 @@ func (m *mockCache) SetSeries(lset Labels, id SeriesID) error {
3436
return m.setSeriesErr
3537
}
3638

39+
func (m *mockCache) NumElements() int {
40+
return len(m.seriesCache)
41+
}
42+
43+
func (m *mockCache) Capacity() int {
44+
return len(m.seriesCache)
45+
}
46+
3747
type mockInserter struct {
3848
insertedSeries map[string]SeriesID
3949
insertedData []map[string][]samplesInfo

pkg/pgmodel/pgx.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ func NewPgxIngestorWithMetricCache(c *pgxpool.Pool, cache MetricCache, cfg *Cfg)
216216

217217
// NewPgxIngestor returns a new Ingestor that write to PostgreSQL using PGX
218218
func NewPgxIngestor(c *pgxpool.Pool) (*DBIngestor, error) {
219-
//TODO what size should we use?
220219
cache := &MetricNameCache{clockcache.WithMax(DefaultMetricCacheSize)}
221220
return NewPgxIngestorWithMetricCache(c, cache, &Cfg{})
222221
}
@@ -913,6 +912,8 @@ type pgxQuerier struct {
913912
labels *clockcache.Cache
914913
}
915914

915+
var _ Querier = (*pgxQuerier)(nil)
916+
916917
// HealthCheck implements the healtchecker interface
917918
func (q *pgxQuerier) HealthCheck() error {
918919
rows, err := q.conn.Query(context.Background(), "SELECT")
@@ -925,6 +926,14 @@ func (q *pgxQuerier) HealthCheck() error {
925926
return nil
926927
}
927928

929+
func (q *pgxQuerier) NumCachedLabels() int {
930+
return q.labels.Len()
931+
}
932+
933+
func (q *pgxQuerier) LabelsCacheCapacity() int {
934+
return q.labels.Cap()
935+
}
936+
928937
func (q *pgxQuerier) Select(mint int64, maxt int64, sortSeries bool, hints *storage.SelectHints, path []parser.Node, ms ...*labels.Matcher) (storage.SeriesSet, parser.Node, storage.Warnings, error) {
929938
rows, topNode, err := q.getResultRows(mint, maxt, hints, path, ms)
930939

pkg/pgmodel/querier.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type Querier interface {
2323
Select(mint int64, maxt int64, sortSeries bool, hints *storage.SelectHints, path []parser.Node, ms ...*labels.Matcher) (storage.SeriesSet, parser.Node, storage.Warnings, error)
2424
LabelNames() ([]string, error)
2525
LabelValues(labelName string) ([]string, error)
26+
NumCachedLabels() int
27+
LabelsCacheCapacity() int
2628
}
2729

2830
//HealthChecker allows checking for proper operations.

0 commit comments

Comments
 (0)