Skip to content

Commit 8fc06c7

Browse files
committed
receive,ruler: Upgraded TSDB and used ChunkIterator in Series TSDB Store.
Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com>
1 parent 7369849 commit 8fc06c7

File tree

4 files changed

+69
-69
lines changed

4 files changed

+69
-69
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ We use *breaking* word for marking changes that are not backward compatible (rel
3232

3333
- [#2893](https://github.com/thanos-io/thanos/pull/2893) Store: Rename metric `thanos_bucket_store_cached_postings_compression_time_seconds` to `thanos_bucket_store_cached_postings_compression_time_seconds_total`.
3434
- [#2915](https://github.com/thanos-io/thanos/pull/2915) Receive,Ruler: Enable TSDB directory locking by default. Add a new flag (`--tsdb.no-lockfile`) to override behavior.
35+
- [#2876](https://github.com/thanos-io/thanos/pull/2876) Receive,Ruler: Updated TSDB and switched to ChunkIterators instead of sample one, which avoids
36+
unnecessary decoding / encoding.
3537

3638
## [v0.14.0](https://github.com/thanos-io/thanos/releases/tag/v0.14.0) - 2020.07.10
3739

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ require (
7373
// See https://github.com/thanos-io/thanos/issues/1415
7474
replace (
7575
// Make sure Cortex is not forcing us to some other Prometheus version.
76-
github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2-0.20200714083622-823b218e1b2e
76+
// TODO: This points to https://github.com/prometheus/prometheus/pull/7069. Remove and point to master once merged.
77+
github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2-0.20200724113653-2605f60545cb
7778
k8s.io/klog => k8s.io/klog v0.3.1
7879
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30
7980
)

go.sum

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
876876
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
877877
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
878878
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
879-
github.com/prometheus/prometheus v1.8.2-0.20200714083622-823b218e1b2e h1:NCV6Sz7qguIRsvG6Aii4wDwWeiUPadaWT/4l4eP7Ax0=
880-
github.com/prometheus/prometheus v1.8.2-0.20200714083622-823b218e1b2e/go.mod h1:F3OdzfA9PNvJ0PxQwHL58k9zOhOLhtcIAOtVqwyYxwk=
879+
github.com/prometheus/prometheus v1.8.2-0.20200724113653-2605f60545cb h1:P2x7BW33WySguYW4ZHG5HaKRI8yOiksDfH56ucTHbwk=
880+
github.com/prometheus/prometheus v1.8.2-0.20200724113653-2605f60545cb/go.mod h1:+/y4DzJ62qmhy0o/H4PtXegRXw+80E8RVRHhLbv+bkM=
881881
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY=
882882
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
883883
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
@@ -1020,6 +1020,8 @@ go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
10201020
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
10211021
go.uber.org/automaxprocs v1.2.0 h1:+RUihKM+nmYUoB9w0D0Ov5TJ2PpFO2FgenTxMJiZBZA=
10221022
go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU=
1023+
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
1024+
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
10231025
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
10241026
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
10251027
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
@@ -1251,6 +1253,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
12511253
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
12521254
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
12531255
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
1256+
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
12541257
golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
12551258
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
12561259
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1334,7 +1337,6 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG
13341337
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
13351338
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
13361339
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
1337-
google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
13381340
google.golang.org/genproto v0.0.0-20200710124503-20a17af7bd0e h1:k+p/u26/lVeNEpdxSeUrm7rTvoFckBKaf7gTzgmHyDA=
13391341
google.golang.org/genproto v0.0.0-20200710124503-20a17af7bd0e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
13401342
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
@@ -1357,7 +1359,6 @@ google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
13571359
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
13581360
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
13591361
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
1360-
google.golang.org/grpc/examples v0.0.0-20200709232328-d8193ee9cc3e/go.mod h1:5j1uub0jRGhRiSghIlrThmBUgcgLXOVJQ/l1getT4uo=
13611362
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
13621363
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
13631364
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

pkg/store/tsdb.go

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/prometheus/client_golang/prometheus"
1414
"github.com/prometheus/prometheus/pkg/labels"
1515
"github.com/prometheus/prometheus/storage"
16-
"github.com/prometheus/prometheus/tsdb/chunkenc"
1716
"google.golang.org/grpc/codes"
1817
"google.golang.org/grpc/status"
1918

@@ -24,18 +23,19 @@ import (
2423
)
2524

2625
type TSDBReader interface {
27-
storage.Queryable
26+
storage.ChunkQueryable
2827
StartTime() (int64, error)
2928
}
3029

3130
// TSDBStore implements the store API against a local TSDB instance.
3231
// It attaches the provided external labels to all results. It only responds with raw data
3332
// and does not support downsampling.
3433
type TSDBStore struct {
35-
logger log.Logger
36-
db TSDBReader
37-
component component.StoreAPI
38-
externalLabels labels.Labels
34+
logger log.Logger
35+
db TSDBReader
36+
component component.StoreAPI
37+
externalLabels labels.Labels
38+
maxBytesPerFrame int
3939
}
4040

4141
// ReadWriteTSDBStore is a TSDBStore that can also be written to.
@@ -50,10 +50,11 @@ func NewTSDBStore(logger log.Logger, _ prometheus.Registerer, db TSDBReader, com
5050
logger = log.NewNopLogger()
5151
}
5252
return &TSDBStore{
53-
logger: logger,
54-
db: db,
55-
component: component,
56-
externalLabels: externalLabels,
53+
logger: logger,
54+
db: db,
55+
component: component,
56+
externalLabels: externalLabels,
57+
maxBytesPerFrame: 1024 * 1024, // 1MB as recommended by gRPC.
5758
}
5859
}
5960

@@ -109,7 +110,7 @@ func (s *TSDBStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesSer
109110
return status.Error(codes.InvalidArgument, err.Error())
110111
}
111112

112-
q, err := s.db.Querier(context.Background(), r.MinTime, r.MaxTime)
113+
q, err := s.db.ChunkQuerier(context.Background(), r.MinTime, r.MaxTime)
113114
if err != nil {
114115
return status.Error(codes.Internal, err.Error())
115116
}
@@ -119,72 +120,67 @@ func (s *TSDBStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesSer
119120
set = q.Select(false, nil, matchers...)
120121
respSeries storepb.Series
121122
)
123+
124+
// Stream at most one series per frame; series may be split over multiple frames according to maxBytesInFrame.
122125
for set.Next() {
123126
series := set.At()
124-
125127
respSeries.Labels = s.translateAndExtendLabels(series.Labels(), s.externalLabels)
126-
127-
if !r.SkipChunks {
128-
// TODO(fabxc): An improvement over this trivial approach would be to directly
129-
// use the chunks provided by TSDB in the response.
130-
c, err := s.encodeChunks(series.Iterator(), MaxSamplesPerChunk)
131-
if err != nil {
132-
return status.Errorf(codes.Internal, "encode chunk: %s", err)
128+
respSeries.Chunks = respSeries.Chunks[:0]
129+
if r.SkipChunks {
130+
if err := srv.Send(storepb.NewSeriesResponse(&respSeries)); err != nil {
131+
return status.Error(codes.Aborted, err.Error())
133132
}
134-
135-
respSeries.Chunks = append(respSeries.Chunks[:0], c...)
133+
continue
136134
}
137135

138-
if err := srv.Send(storepb.NewSeriesResponse(&respSeries)); err != nil {
139-
return status.Error(codes.Aborted, err.Error())
136+
frameBytesLeft := s.maxBytesPerFrame
137+
for _, lbl := range respSeries.Labels {
138+
frameBytesLeft -= lbl.Size()
140139
}
141-
}
142-
if err := set.Err(); err != nil {
143-
return status.Error(codes.Internal, err.Error())
144-
}
145-
return nil
146-
}
147-
148-
func (s *TSDBStore) encodeChunks(it chunkenc.Iterator, maxSamplesPerChunk int) (chks []storepb.AggrChunk, err error) {
149-
var (
150-
chkMint int64
151-
chk *chunkenc.XORChunk
152-
app chunkenc.Appender
153-
isNext = it.Next()
154-
)
155140

156-
for isNext {
157-
if chk == nil {
158-
chk = chunkenc.NewXORChunk()
159-
app, err = chk.Appender()
160-
if err != nil {
161-
return nil, err
141+
chIter := series.Iterator()
142+
isNext := chIter.Next()
143+
for isNext {
144+
chk := chIter.At()
145+
if chk.Chunk == nil {
146+
return status.Errorf(codes.Internal, "TSDBStore: found not populated chunk returned by SeriesSet at ref: %v", chk.Ref)
162147
}
163-
chkMint, _ = it.At()
164-
}
165148

166-
app.Append(it.At())
167-
chkMaxt, _ := it.At()
149+
respSeries.Chunks = append(respSeries.Chunks, storepb.AggrChunk{
150+
MinTime: chk.MinTime,
151+
MaxTime: chk.MaxTime,
152+
Raw: &storepb.Chunk{
153+
Type: storepb.Chunk_Encoding(chk.Chunk.Encoding() - 1), // proto chunk encoding is one off to TSDB one.
154+
Data: chk.Chunk.Bytes(),
155+
},
156+
})
157+
frameBytesLeft -= respSeries.Chunks[len(respSeries.Chunks)-1].Size()
158+
159+
// We are fine with minor inaccuracy of max bytes per frame. The inaccuracy will be max of full chunk size.
160+
isNext = chIter.Next()
161+
if frameBytesLeft > 0 && isNext {
162+
continue
163+
}
168164

169-
isNext = it.Next()
170-
if isNext && chk.NumSamples() < maxSamplesPerChunk {
171-
continue
165+
if err := srv.Send(storepb.NewSeriesResponse(&respSeries)); err != nil {
166+
return status.Error(codes.Aborted, err.Error())
167+
}
168+
respSeries.Chunks = respSeries.Chunks[:0]
169+
}
170+
if err := chIter.Err(); err != nil {
171+
return status.Error(codes.Internal, errors.Wrap(err, "chunk iter").Error())
172172
}
173173

174-
// Cut the chunk.
175-
chks = append(chks, storepb.AggrChunk{
176-
MinTime: chkMint,
177-
MaxTime: chkMaxt,
178-
Raw: &storepb.Chunk{Type: storepb.Chunk_XOR, Data: chk.Bytes()},
179-
})
180-
chk = nil
181174
}
182-
if it.Err() != nil {
183-
return nil, errors.Wrap(it.Err(), "read TSDB series")
175+
if err := set.Err(); err != nil {
176+
return status.Error(codes.Internal, err.Error())
177+
}
178+
for _, w := range set.Warnings() {
179+
if err := srv.Send(storepb.NewWarnSeriesResponse(w)); err != nil {
180+
return status.Error(codes.Aborted, err.Error())
181+
}
184182
}
185-
186-
return chks, nil
187-
183+
return nil
188184
}
189185

190186
// translateAndExtendLabels transforms a metrics into a protobuf label set. It additionally
@@ -217,7 +213,7 @@ func (s *TSDBStore) translateAndExtendLabels(m, extend labels.Labels) []storepb.
217213
func (s *TSDBStore) LabelNames(ctx context.Context, _ *storepb.LabelNamesRequest) (
218214
*storepb.LabelNamesResponse, error,
219215
) {
220-
q, err := s.db.Querier(ctx, math.MinInt64, math.MaxInt64)
216+
q, err := s.db.ChunkQuerier(ctx, math.MinInt64, math.MaxInt64)
221217
if err != nil {
222218
return nil, status.Error(codes.Internal, err.Error())
223219
}
@@ -234,7 +230,7 @@ func (s *TSDBStore) LabelNames(ctx context.Context, _ *storepb.LabelNamesRequest
234230
func (s *TSDBStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequest) (
235231
*storepb.LabelValuesResponse, error,
236232
) {
237-
q, err := s.db.Querier(ctx, math.MinInt64, math.MaxInt64)
233+
q, err := s.db.ChunkQuerier(ctx, math.MinInt64, math.MaxInt64)
238234
if err != nil {
239235
return nil, status.Error(codes.Internal, err.Error())
240236
}

0 commit comments

Comments
 (0)