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

Add PromQL query and query_range support #124

Merged
merged 3 commits into from
Jun 22, 2020
Merged

Conversation

atanasovskib
Copy link
Contributor

By using the Prometheus QueryEngine we enable
Timescale-Prometheus to return results for query and query_range
PromQL requests.

Blagoj Atanasovski and others added 2 commits June 15, 2020 18:31
By using the Prometheus QueryEngine and some utility functions
from the Querier implementation for remote storage we enable
Timescale-Prometheus to return results for query and query_range
PromQL requests. Implementation is rudimentary, only direct
requests to these two endpoints can be executed. Needs implementation
of the methods that return metadata.
@@ -64,7 +68,8 @@ type MetricCache interface {
}

type pgxConnImpl struct {
conn *pgxpool.Pool
conn *pgxpool.Pool
readHist prometheus.ObserverVec
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this only seems to be needed on the Query side, can we add it to some reader-only state instead?

@@ -677,19 +690,64 @@ func (q *pgxQuerier) HealthCheck() error {
return nil
}

func (q *pgxQuerier) Select(mint int64, maxt int64, sortSeries bool, hints *storage.SelectHints, ms ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sinve all of this stuff seems to be non-pgx specific, should it go in querier.go, or another file, instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ but probably not for this PR (It also requires moving Query function below and maybe some other things; This PR is already big). I'd add a todo on the project board or an issue.

return found
}

func (p *pgxSeriesIterator) getCurrTs() int64 {
Copy link
Contributor

@JLockerman JLockerman Jun 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this return a model.Time?
(btw, I have a version with what I believe to be correct overflow handling here, not sure how much we care)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implements a prometheus defined interface

@@ -182,6 +153,12 @@ func (c *clauseBuilder) build() ([]string, []interface{}) {
return c.clauses, c.args
}

func buildSeriesSet(rows []pgx.Rows, sortSeries bool) (storage.SeriesSet, storage.Warnings, error) {
return &pgxSeriesSet{
rows: rows,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly tempted to say we should just write our own type with our own DecodeBinary, and return the query results directly as the iterator, but I'm not sure if it's worth.

pkg/pgmodel/series_set.go Outdated Show resolved Hide resolved
pkg/pgmodel/series_set.go Outdated Show resolved Hide resolved
@JLockerman
Copy link
Contributor

I also don't like how the decoding code is using arbitrary-seeming array-indexes everywhere; at minimum I'd like documentation for expected layout, and ideally I'd like pgx to error if the postgres types don't match the type we expect

Copy link
Contributor

@cevian cevian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work. I think the thing that need the most changing is the series set stuff. The code right now is pretty complex and doesn't handle nulls. The advantages of the approach are unclear because of the need to copy the byte slice anyway. I suggested a slightly different approach that may not be quite as efficient but I think is cleaner for now until we get some profiling data.

pkg/api/ranged_query.go Show resolved Hide resolved
cmd/timescale-prometheus/main.go Show resolved Hide resolved
pkg/api/health.go Show resolved Hide resolved
@@ -0,0 +1,145 @@
package api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make issues/todos for creating query_test and query_range tests just like the other endpoints? Not to be implemented for this PR.

@@ -677,19 +690,64 @@ func (q *pgxQuerier) HealthCheck() error {
return nil
}

func (q *pgxQuerier) Select(mint int64, maxt int64, sortSeries bool, hints *storage.SelectHints, ms ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ but probably not for this PR (It also requires moving Query function below and maybe some other things; This PR is already big). I'd add a todo on the project board or an issue.

pkg/pgmodel/series_set.go Show resolved Hide resolved
pkg/promql/query_engine.go Show resolved Hide resolved
pkg/promql/queryable.go Show resolved Hide resolved
pkg/promql/queryable.go Show resolved Hide resolved
pkg/promql/queryable.go Show resolved Hide resolved
@cevian
Copy link
Contributor

cevian commented Jun 15, 2020

This also needs a rebase

pkg/api/health_test.go Show resolved Hide resolved
pkg/api/read.go Show resolved Hide resolved
pkg/api/write_test.go Show resolved Hide resolved
pkg/prompb/query.go Outdated Show resolved Hide resolved
pkg/prompb/query.go Outdated Show resolved Hide resolved
pkg/prompb/query.go Outdated Show resolved Hide resolved
@antekresic
Copy link
Contributor

@cevian @JLockerman I've updated the PR with your suggestion. I didn't include the overflow checks as suggested but we really care, can add those as well.

Can you take another look? Thanks!

Copy link
Contributor

@cevian cevian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of the series_set stuff only. @antekresic looks much better. Have a few change requests with regard to proper NULL handling.

pkg/pgmodel/series_set.go Show resolved Hide resolved
pkg/pgmodel/series_set.go Show resolved Hide resolved
pkg/pgmodel/series_set.go Show resolved Hide resolved
pkg/pgmodel/series_set.go Outdated Show resolved Hide resolved
pkg/pgmodel/series_set.go Show resolved Hide resolved
Copy link
Contributor

@cevian cevian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some easy to implement nits remaining.

pkg/prompb/query.go Outdated Show resolved Hide resolved
pkg/prompb/labels.go Outdated Show resolved Hide resolved
@JLockerman
Copy link
Contributor

further I think this code may be a problem; if I'm reading it right it'll send the queries one-at-a-time to the database, and incur latency proportional to the number of metrics, if we batched them we would only have 1 round-trip-time. Additionally, if we batched them that function could return a BatchResults, and we wouldn't have to store []Rows everywhere.

@JLockerman
Copy link
Contributor

(that last bit should probably wait for the next PR)

In order to reduce the performance impact of transforming the
data coming from the database in multiple formats, this commits
adds the ability to read the values from binary data as its needed
by the query engine.
@antekresic
Copy link
Contributor

@cevian @JLockerman updated the PR with the latest comments and created a new issue for Joshes comment: #128

Copy link
Contributor

@JLockerman JLockerman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved with nit

@@ -168,3 +169,29 @@ func (l *Labels) Swap(i, j int) {
l.values[j] = l.values[i]
l.values[i] = tmp
}

// FromLabelMatchers parses protobuf label matchers to Prometheus label matchers.
func FromLabelMatchers(matchers []*prompb.LabelMatcher) ([]*labels.Matcher, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't really belong here either, this is for our own Labels datatype 🤔

@atanasovskib atanasovskib merged commit e44ce74 into master Jun 22, 2020
@atanasovskib atanasovskib deleted the add-promql-endpoint branch June 22, 2020 12:42
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants