Skip to content

Commit

Permalink
Add thanos query frontend sub command (#2973)
Browse files Browse the repository at this point in the history
* add thanos query frontend sub command

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* remove disable-step-align flag

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* check empty downstream url

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* remove userID in cache key

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* add flags max-query-length and max-query-parallelelism

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* Add E2E test for query frontend

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* add unit tests for roundtripper

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* add changelog

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* add config flags for Cortex fifo cache

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* add response cache config

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* don't create cache middleware when splitQueryInterval == 0 to prevent panic

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* fix windows build failure

Signed-off-by: Ben Ye <yb532204897@gmail.com>

* refactor handler; add more test cases to e2e and unit tests

Signed-off-by: Ben Ye <yb532204897@gmail.com>
  • Loading branch information
yeya24 committed Aug 11, 2020
1 parent d640a1a commit 2ea2c2b
Show file tree
Hide file tree
Showing 17 changed files with 1,188 additions and 145 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ We use *breaking* word for marking changes that are not backward compatible (rel
- [#2865](https://github.com/thanos-io/thanos/pull/2865) ui: Migrate Thanos Ruler UI to React
- [#2964](https://github.com/thanos-io/thanos/pull/2964) Query: Add time range parameters to label APIs. Add `start` and `end` fields to Store API `LabelNamesRequest` and `LabelValuesRequest`.
- [#2996](https://github.com/thanos-io/thanos/pull/2996) Sidecar: Add `reloader_config_apply_errors_total` metric. Add new flags `--reloader.watch-interval`, and `--reloader.retry-interval`.
- [#2973](https://github.com/thanos-io/thanos/pull/2973) Add Thanos Query Frontend component.

### Changed

Expand Down
4 changes: 1 addition & 3 deletions cmd/thanos/compact.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ type compactConfig struct {
label string
}

func (cc *compactConfig) registerFlag(cmd *kingpin.CmdClause) *compactConfig {
func (cc *compactConfig) registerFlag(cmd *kingpin.CmdClause) {
cmd.Flag("debug.halt-on-error", "Halt the process if a critical compaction error is detected.").
Hidden().Default("true").BoolVar(&cc.haltOnError)
cmd.Flag("debug.accept-malformed-index",
Expand Down Expand Up @@ -531,6 +531,4 @@ func (cc *compactConfig) registerFlag(cmd *kingpin.CmdClause) *compactConfig {
cc.webConf.registerFlag(cmd)

cmd.Flag("bucket-web-label", "Prometheus label to use as timeline title in the bucket web UI").StringVar(&cc.label)

return cc
}
1 change: 1 addition & 0 deletions cmd/thanos/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func main() {
registerCompact(cmds, app)
registerTools(cmds, app)
registerReceive(cmds, app)
registerQueryFrontend(cmds, app)

cmd, err := app.Parse(os.Args[1:])
if err != nil {
Expand Down
187 changes: 187 additions & 0 deletions cmd/thanos/query-frontend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.

package main

import (
"net/http"
"time"

"github.com/cortexproject/cortex/pkg/querier/frontend"
"github.com/cortexproject/cortex/pkg/querier/queryrange"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/oklog/run"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
"github.com/weaveworks/common/user"
"gopkg.in/alecthomas/kingpin.v2"

"github.com/thanos-io/thanos/pkg/component"
"github.com/thanos-io/thanos/pkg/extflag"
"github.com/thanos-io/thanos/pkg/extprom"
"github.com/thanos-io/thanos/pkg/prober"
"github.com/thanos-io/thanos/pkg/queryfrontend"
"github.com/thanos-io/thanos/pkg/queryfrontend/cache"
httpserver "github.com/thanos-io/thanos/pkg/server/http"
)

type queryFrontendConfig struct {
http httpConfig
queryRangeConfig queryRangeConfig

downstreamURL string
compressResponses bool
LogQueriesLongerThan time.Duration
}

type queryRangeConfig struct {
respCacheConfig extflag.PathOrContent
cacheMaxFreshness time.Duration
splitInterval model.Duration
maxRetries int
maxQueryParallelism int
maxQueryLength model.Duration
}

func (c *queryRangeConfig) registerFlag(cmd *kingpin.CmdClause) {
cmd.Flag("query-range.split-interval", "Split queries by an interval and execute in parallel, 0 disables it.").
Default("24h").SetValue(&c.splitInterval)

cmd.Flag("query-range.max-retries-per-request", "Maximum number of retries for a single request; beyond this, the downstream error is returned.").
Default("5").IntVar(&c.maxRetries)

cmd.Flag("query-range.max-query-length", "Limit the query time range (end - start time) in the query-frontend, 0 disables it.").
Default("0").SetValue(&c.maxQueryLength)

cmd.Flag("query-range.max-query-parallelism", "Maximum number of queries will be scheduled in parallel by the frontend.").
Default("14").IntVar(&c.maxQueryParallelism)

cmd.Flag("query-range.response-cache-max-freshness", "Most recent allowed cacheable result, to prevent caching very recent results that might still be in flux.").
Default("1m").DurationVar(&c.cacheMaxFreshness)

c.respCacheConfig = *extflag.RegisterPathOrContent(cmd, "query-range.response-cache-config", "YAML file that contains response cache configuration.", false)
}

func (c *queryFrontendConfig) registerFlag(cmd *kingpin.CmdClause) {
c.queryRangeConfig.registerFlag(cmd)
c.http.registerFlag(cmd)

cmd.Flag("query-frontend.downstream-url", "URL of downstream Prometheus Query compatible API.").
Default("http://localhost:9090").StringVar(&c.downstreamURL)

cmd.Flag("query-frontend.compress-responses", "Compress HTTP responses.").
Default("false").BoolVar(&c.compressResponses)

cmd.Flag("query-frontend.log_queries_longer_than", "Log queries that are slower than the specified duration. "+
"Set to 0 to disable. Set to < 0 to enable on all queries.").Default("0").DurationVar(&c.LogQueriesLongerThan)
}

func registerQueryFrontend(m map[string]setupFunc, app *kingpin.Application) {
comp := component.QueryFrontend
cmd := app.Command(comp.String(), "query frontend")
conf := &queryFrontendConfig{}
conf.registerFlag(cmd)

m[comp.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error {
return runQueryFrontend(g, logger, reg, conf, comp)
}
}

func runQueryFrontend(
g *run.Group,
logger log.Logger,
reg *prometheus.Registry,
conf *queryFrontendConfig,
comp component.Component,
) error {

if len(conf.downstreamURL) == 0 {
return errors.New("downstream URL should be configured")
}

fe, err := frontend.New(frontend.Config{
DownstreamURL: conf.downstreamURL,
CompressResponses: conf.compressResponses,
LogQueriesLongerThan: conf.LogQueriesLongerThan,
}, logger, reg)
if err != nil {
return errors.Wrap(err, "setup query frontend")
}
defer fe.Close()

limits := queryfrontend.NewLimits(
conf.queryRangeConfig.maxQueryParallelism,
time.Duration(conf.queryRangeConfig.maxQueryLength),
conf.queryRangeConfig.cacheMaxFreshness,
)

respCacheContentYaml, err := conf.queryRangeConfig.respCacheConfig.Content()
if err != nil {
return errors.Wrap(err, "get content of response cache configuration")
}

var cacheConfig *queryrange.ResultsCacheConfig
if len(respCacheContentYaml) > 0 {
cacheConfig, err = cache.NewResponseCacheConfig(respCacheContentYaml)
if err != nil {
return errors.Wrap(err, "create response cache")
}
}

tripperWare, err := queryfrontend.NewTripperWare(
limits,
cacheConfig,
queryrange.PrometheusCodec,
queryrange.PrometheusResponseExtractor{},
time.Duration(conf.queryRangeConfig.splitInterval),
conf.queryRangeConfig.maxRetries,
reg,
logger,
)
if err != nil {
return errors.Wrap(err, "setup query range middlewares")
}

fe.Wrap(tripperWare)

httpProbe := prober.NewHTTP()
statusProber := prober.Combine(
httpProbe,
prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)),
)

// Start metrics HTTP server.
{
srv := httpserver.New(logger, reg, comp, httpProbe,
httpserver.WithListen(conf.http.bindAddress),
httpserver.WithGracePeriod(time.Duration(conf.http.gracePeriod)),
)

injectf := func(f http.HandlerFunc) http.HandlerFunc {
hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Cortex frontend middlewares require orgID.
f.ServeHTTP(w, r.WithContext(user.InjectOrgID(r.Context(), "fake")))
})
return hf
}
srv.Handle("/", injectf(fe.Handler().ServeHTTP))

g.Add(func() error {
statusProber.Healthy()

return srv.ListenAndServe()
}, func(err error) {
statusProber.NotReady(err)
defer statusProber.NotHealthy(err)

srv.Shutdown(err)
})
}

level.Info(logger).Log("msg", "starting query frontend")
statusProber.Ready()
return nil
}
3 changes: 1 addition & 2 deletions cmd/thanos/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ type sidecarConfig struct {
limitMinTime thanosmodel.TimeOrDurationValue
}

func (sc *sidecarConfig) registerFlag(cmd *kingpin.CmdClause) *sidecarConfig {
func (sc *sidecarConfig) registerFlag(cmd *kingpin.CmdClause) {
sc.http.registerFlag(cmd)
sc.grpc.registerFlag(cmd)
sc.prometheus.registerFlag(cmd)
Expand All @@ -426,5 +426,4 @@ func (sc *sidecarConfig) registerFlag(cmd *kingpin.CmdClause) *sidecarConfig {
sc.shipper.registerFlag(cmd)
cmd.Flag("min-time", "Start of time range limit to serve. Thanos sidecar will serve only metrics, which happened later than this value. Option can be a constant time in RFC3339 format or time duration relative to current time, such as -1d or 2h45m. Valid duration units are ms, s, m, h, d, w, y.").
Default("0000-01-01T00:00:00Z").SetValue(&sc.limitMinTime)
return sc
}
12 changes: 9 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible
github.com/armon/go-metrics v0.3.3
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
github.com/cespare/xxhash v1.1.0
github.com/chromedp/cdproto v0.0.0-20200424080200-0de008e41fa0
Expand All @@ -30,7 +31,6 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/golang-lru v0.5.4
github.com/jpillora/backoff v1.0.0
github.com/klauspost/cpuid v1.3.1 // indirect
github.com/leanovate/gopter v0.2.4
github.com/lightstep/lightstep-tracer-go v0.18.1
github.com/lovoo/gcloud-opentracing v0.3.0
Expand All @@ -49,17 +49,17 @@ require (
github.com/prometheus/client_golang v1.7.1
github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.11.1
github.com/prometheus/prometheus v1.8.2-0.20200805082714-e0cf219f0de2
github.com/prometheus/prometheus v1.8.2-0.20200807135816-2899773b0159
github.com/uber/jaeger-client-go v2.25.0+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/weaveworks/common v0.0.0-20200625145055-4b1847531bc9
go.elastic.co/apm v1.5.0
go.elastic.co/apm/module/apmot v1.5.0
go.uber.org/atomic v1.6.0
go.uber.org/automaxprocs v1.2.0
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 // indirect
golang.org/x/text v0.3.3
google.golang.org/api v0.29.0
google.golang.org/genproto v0.0.0-20200724131911-43cab4749ae7
Expand All @@ -74,8 +74,14 @@ require (
// so that we don't get errors about being incompatible with the Go proxies.
// See https://github.com/thanos-io/thanos/issues/1415
replace (
// TODO(yeya24): This is just a temporary fork. Update it after
// https://github.com/cortexproject/cortex/pull/3000 is merged.
github.com/cortexproject/cortex => github.com/yeya24/cortex v0.2.0-rc.0.0.20200808202232-e79e9acd4e4d
// Update to v1.1.1 to make sure windows CI pass.
github.com/elastic/go-sysinfo => github.com/elastic/go-sysinfo v1.1.1
// Make sure Prometheus version is pinned as Prometheus semver does not include Go APIs.
github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2-0.20200807135816-2899773b0159
github.com/sercand/kuberesolver => github.com/sercand/kuberesolver v2.4.0+incompatible
google.golang.org/grpc => google.golang.org/grpc v1.29.1
k8s.io/klog => k8s.io/klog v0.3.1
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30
Expand Down
Loading

0 comments on commit 2ea2c2b

Please sign in to comment.