Skip to content

Commit

Permalink
Add number tenants per query histogram
Browse files Browse the repository at this point in the history
Signed-off-by: SungJin1212 <[email protected]>
  • Loading branch information
SungJin1212 committed Dec 20, 2024
1 parent bb59466 commit d5beaf8
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [FEATURE] Chunk Cache: Support multi level cache and add metrics. #6249
* [FEATURE] Distributor: Accept multiple HA Tracker pairs in the same request. #6256
* [FEATURE] Ruler: Add support for per-user external labels #6340
* [ENHANCEMENT] Querier: Add a `cortex_querier_federated_tenants_per_query` histogram to track the number of tenants per query when the `-tenant-federation.enabled=true`. #6447
* [ENHANCEMENT] Query Frontend: Add a number of series in the query response to the query stat log. #6423
* [ENHANCEMENT] Store Gateway: Add a hedged request to reduce the tail latency. #6388
* [ENHANCEMENT] Ingester: Add metrics to track succeed/failed native histograms. #6370
Expand Down
3 changes: 2 additions & 1 deletion pkg/cortex/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,13 @@ func (t *Cortex) initQueryable() (serv services.Service, err error) {

// Enable merge querier if multi tenant query federation is enabled
func (t *Cortex) initTenantFederation() (serv services.Service, err error) {

if t.Cfg.TenantFederation.Enabled {
// Make sure the mergeQuerier is only used for request with more than a
// single tenant. This allows for a less impactful enabling of tenant
// federation.
byPassForSingleQuerier := true
t.QuerierQueryable = querier.NewSampleAndChunkQueryable(tenantfederation.NewQueryable(t.QuerierQueryable, byPassForSingleQuerier))
t.QuerierQueryable = querier.NewSampleAndChunkQueryable(tenantfederation.NewQueryable(t.QuerierQueryable, byPassForSingleQuerier, prometheus.DefaultRegisterer))
}
return nil, nil
}
Expand Down
24 changes: 21 additions & 3 deletions pkg/querier/tenantfederation/merge_queryable.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"

"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb/chunkenc"
Expand Down Expand Up @@ -36,8 +38,8 @@ const (
// If the label "__tenant_id__" is already existing, its value is overwritten
// by the tenant ID and the previous value is exposed through a new label
// prefixed with "original_". This behaviour is not implemented recursively.
func NewQueryable(upstream storage.Queryable, byPassWithSingleQuerier bool) storage.Queryable {
return NewMergeQueryable(defaultTenantLabel, tenantQuerierCallback(upstream), byPassWithSingleQuerier)
func NewQueryable(upstream storage.Queryable, byPassWithSingleQuerier bool, reg prometheus.Registerer) storage.Queryable {
return NewMergeQueryable(defaultTenantLabel, tenantQuerierCallback(upstream), byPassWithSingleQuerier, reg)
}

func tenantQuerierCallback(queryable storage.Queryable) MergeQuerierCallback {
Expand Down Expand Up @@ -79,18 +81,26 @@ type MergeQuerierCallback func(ctx context.Context, mint int64, maxt int64) (ids
// If the label `idLabelName` is already existing, its value is overwritten and
// the previous value is exposed through a new label prefixed with "original_".
// This behaviour is not implemented recursively.
func NewMergeQueryable(idLabelName string, callback MergeQuerierCallback, byPassWithSingleQuerier bool) storage.Queryable {
func NewMergeQueryable(idLabelName string, callback MergeQuerierCallback, byPassWithSingleQuerier bool, reg prometheus.Registerer) storage.Queryable {
return &mergeQueryable{
idLabelName: idLabelName,
callback: callback,
byPassWithSingleQuerier: byPassWithSingleQuerier,

tenantsPerQuery: promauto.With(reg).NewHistogram(prometheus.HistogramOpts{
Namespace: "cortex",
Name: "querier_federated_tenants_per_query",
Help: "Number of tenants per query.",
Buckets: []float64{1, 2, 4, 8, 16, 32, 64},
}),
}
}

type mergeQueryable struct {
idLabelName string
byPassWithSingleQuerier bool
callback MergeQuerierCallback
tenantsPerQuery prometheus.Histogram
}

// Querier returns a new mergeQuerier, which aggregates results from multiple
Expand All @@ -102,6 +112,7 @@ func (m *mergeQueryable) Querier(mint int64, maxt int64) (storage.Querier, error
maxt: maxt,
byPassWithSingleQuerier: m.byPassWithSingleQuerier,
callback: m.callback,
tenantsPerQuery: m.tenantsPerQuery,
}, nil
}

Expand All @@ -117,6 +128,7 @@ type mergeQuerier struct {
callback MergeQuerierCallback

byPassWithSingleQuerier bool
tenantsPerQuery prometheus.Histogram
}

// LabelValues returns all potential values for a label name. It is not safe
Expand All @@ -130,6 +142,8 @@ func (m *mergeQuerier) LabelValues(ctx context.Context, name string, hints *stor
return nil, nil, err
}

m.tenantsPerQuery.Observe(float64(len(ids)))

// by pass when only single querier is returned
if m.byPassWithSingleQuerier && len(queriers) == 1 {
return queriers[0].LabelValues(ctx, name, hints, matchers...)
Expand Down Expand Up @@ -169,6 +183,8 @@ func (m *mergeQuerier) LabelNames(ctx context.Context, hints *storage.LabelHints
return nil, nil, err
}

m.tenantsPerQuery.Observe(float64(len(ids)))

// by pass when only single querier is returned
if m.byPassWithSingleQuerier && len(queriers) == 1 {
return queriers[0].LabelNames(ctx, hints, matchers...)
Expand Down Expand Up @@ -309,6 +325,8 @@ func (m *mergeQuerier) Select(ctx context.Context, sortSeries bool, hints *stora
return storage.ErrSeriesSet(err)
}

m.tenantsPerQuery.Observe(float64(len(ids)))

// by pass when only single querier is returned
if m.byPassWithSingleQuerier && len(queriers) == 1 {
return queriers[0].Select(ctx, sortSeries, hints, matchers...)
Expand Down
Loading

0 comments on commit d5beaf8

Please sign in to comment.