Implement series API query hint to not hit chunks (#8050)

Fixes https://github.com/prometheus/prometheus/issues/5547

Signed-off-by: Goutham Veeramachaneni <gouthamve@gmail.com>
This commit is contained in:
Goutham Veeramachaneni 2020-10-14 11:06:17 +02:00 committed by GitHub
parent 9145200842
commit 1cc02930b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 6 deletions

View File

@ -120,11 +120,6 @@ func NewBlockQuerier(b BlockReader, mint, maxt int64) (storage.Querier, error) {
func (q *blockQuerier) Select(sortSeries bool, hints *storage.SelectHints, ms ...*labels.Matcher) storage.SeriesSet { func (q *blockQuerier) Select(sortSeries bool, hints *storage.SelectHints, ms ...*labels.Matcher) storage.SeriesSet {
mint := q.mint mint := q.mint
maxt := q.maxt maxt := q.maxt
if hints != nil {
mint = hints.Start
maxt = hints.End
}
p, err := PostingsForMatchers(q.index, ms...) p, err := PostingsForMatchers(q.index, ms...)
if err != nil { if err != nil {
return storage.ErrSeriesSet(err) return storage.ErrSeriesSet(err)
@ -132,6 +127,16 @@ func (q *blockQuerier) Select(sortSeries bool, hints *storage.SelectHints, ms ..
if sortSeries { if sortSeries {
p = q.index.SortedPostings(p) p = q.index.SortedPostings(p)
} }
if hints != nil {
mint = hints.Start
maxt = hints.End
if hints.Func == "series" {
// When you're only looking up metadata (for example series API), you don't need to load any chunks.
return newBlockSeriesSet(q.index, newNopChunkReader(), q.tombstones, p, mint, maxt)
}
}
return newBlockSeriesSet(q.index, q.chunks, q.tombstones, p, mint, maxt) return newBlockSeriesSet(q.index, q.chunks, q.tombstones, p, mint, maxt)
} }
@ -821,3 +826,17 @@ Outer:
} }
func (it *deletedIterator) Err() error { return it.it.Err() } func (it *deletedIterator) Err() error { return it.it.Err() }
type nopChunkReader struct {
emptyChunk chunkenc.Chunk
}
func newNopChunkReader() ChunkReader {
return nopChunkReader{
emptyChunk: chunkenc.NewXORChunk(),
}
}
func (cr nopChunkReader) Chunk(ref uint64) (chunkenc.Chunk, error) { return cr.emptyChunk, nil }
func (cr nopChunkReader) Close() error { return nil }

View File

@ -602,10 +602,16 @@ func (api *API) series(r *http.Request) (result apiFuncResult) {
q.Close() q.Close()
} }
hints := &storage.SelectHints{
Start: timestamp.FromTime(start),
End: timestamp.FromTime(end),
Func: "series", // There is no series function, this token is used for lookups that don't need samples.
}
var sets []storage.SeriesSet var sets []storage.SeriesSet
for _, mset := range matcherSets { for _, mset := range matcherSets {
// We need to sort this select results to merge (deduplicate) the series sets later. // We need to sort this select results to merge (deduplicate) the series sets later.
s := q.Select(true, nil, mset...) s := q.Select(true, hints, mset...)
sets = append(sets, s) sets = append(sets, s)
} }