-
Notifications
You must be signed in to change notification settings - Fork 839
Add ingesters shuffle sharding support on the read path #3252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6d8dc72
3791c04
89f7ed4
c691da8
1a0d1ab
0d4249f
90285ef
cb186c4
6ffc73f
8c39891
d8abef7
33bd6dd
2b8032c
f5211d0
4104dc6
44b50fd
a08b64c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -170,6 +170,9 @@ type Config struct { | |
| // when true the distributor does not validate the label name, Cortex doesn't directly use | ||
| // this (and should never use it) but this feature is used by other projects built on top of it | ||
| SkipLabelNameValidation bool `yaml:"-"` | ||
|
|
||
| // This config is dynamically injected because defined in the querier config. | ||
| ShuffleShardingLookbackPeriod time.Duration `yaml:"-"` | ||
| } | ||
|
|
||
| // RegisterFlags adds the flags required to config this to the given FlagSet | ||
|
|
@@ -622,16 +625,8 @@ func (d *Distributor) send(ctx context.Context, ingester ring.IngesterDesc, time | |
| return err | ||
| } | ||
|
|
||
| // ForAllIngesters runs f, in parallel, for all ingesters | ||
| func (d *Distributor) ForAllIngesters(ctx context.Context, reallyAll bool, f func(context.Context, client.IngesterClient) (interface{}, error)) ([]interface{}, error) { | ||
| replicationSet, err := d.ingestersRing.GetAll(ring.Read) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if reallyAll { | ||
| replicationSet.MaxErrors = 0 | ||
|
||
| } | ||
|
|
||
| // ForReplicationSet runs f, in parallel, for all ingesters in the input replication set. | ||
| func (d *Distributor) ForReplicationSet(ctx context.Context, replicationSet ring.ReplicationSet, f func(context.Context, client.IngesterClient) (interface{}, error)) ([]interface{}, error) { | ||
| return replicationSet.Do(ctx, d.cfg.ExtraQueryDelay, func(ctx context.Context, ing *ring.IngesterDesc) (interface{}, error) { | ||
| client, err := d.ingesterPool.GetClientFor(ing.Addr) | ||
| if err != nil { | ||
|
|
@@ -644,10 +639,15 @@ func (d *Distributor) ForAllIngesters(ctx context.Context, reallyAll bool, f fun | |
|
|
||
| // LabelValuesForLabelName returns all of the label values that are associated with a given label name. | ||
| func (d *Distributor) LabelValuesForLabelName(ctx context.Context, labelName model.LabelName) ([]string, error) { | ||
| replicationSet, err := d.getIngestersForMetadata(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| req := &client.LabelValuesRequest{ | ||
| LabelName: string(labelName), | ||
| } | ||
| resps, err := d.ForAllIngesters(ctx, false, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| resps, err := d.ForReplicationSet(ctx, replicationSet, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| return client.LabelValues(ctx, req) | ||
| }) | ||
| if err != nil { | ||
|
|
@@ -670,8 +670,13 @@ func (d *Distributor) LabelValuesForLabelName(ctx context.Context, labelName mod | |
|
|
||
| // LabelNames returns all of the label names. | ||
| func (d *Distributor) LabelNames(ctx context.Context) ([]string, error) { | ||
| replicationSet, err := d.getIngestersForMetadata(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| req := &client.LabelNamesRequest{} | ||
| resps, err := d.ForAllIngesters(ctx, false, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| resps, err := d.ForReplicationSet(ctx, replicationSet, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| return client.LabelNames(ctx, req) | ||
| }) | ||
| if err != nil { | ||
|
|
@@ -698,12 +703,17 @@ func (d *Distributor) LabelNames(ctx context.Context) ([]string, error) { | |
|
|
||
| // MetricsForLabelMatchers gets the metrics that match said matchers | ||
| func (d *Distributor) MetricsForLabelMatchers(ctx context.Context, from, through model.Time, matchers ...*labels.Matcher) ([]metric.Metric, error) { | ||
| replicationSet, err := d.getIngestersForMetadata(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| req, err := ingester_client.ToMetricsForLabelMatchersRequest(from, through, matchers) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| resps, err := d.ForAllIngesters(ctx, false, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| resps, err := d.ForReplicationSet(ctx, replicationSet, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| return client.MetricsForLabelMatchers(ctx, req) | ||
| }) | ||
| if err != nil { | ||
|
|
@@ -729,9 +739,14 @@ func (d *Distributor) MetricsForLabelMatchers(ctx context.Context, from, through | |
|
|
||
| // MetricsMetadata returns all metric metadata of a user. | ||
| func (d *Distributor) MetricsMetadata(ctx context.Context) ([]scrape.MetricMetadata, error) { | ||
| replicationSet, err := d.getIngestersForMetadata(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| req := &ingester_client.MetricsMetadataRequest{} | ||
| // TODO(gotjosh): We only need to look in all the ingesters if shardByAllLabels is enabled. | ||
| resps, err := d.ForAllIngesters(ctx, false, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| resps, err := d.ForReplicationSet(ctx, replicationSet, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| return client.MetricsMetadata(ctx, req) | ||
| }) | ||
| if err != nil { | ||
|
|
@@ -764,8 +779,16 @@ func (d *Distributor) MetricsMetadata(ctx context.Context) ([]scrape.MetricMetad | |
|
|
||
| // UserStats returns statistics about the current user. | ||
| func (d *Distributor) UserStats(ctx context.Context) (*UserStats, error) { | ||
| replicationSet, err := d.getIngestersForMetadata(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // Make sure we get a successful response from all of them. | ||
| replicationSet.MaxErrors = 0 | ||
|
|
||
| req := &client.UserStatsRequest{} | ||
| resps, err := d.ForAllIngesters(ctx, true, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| resps, err := d.ForReplicationSet(ctx, replicationSet, func(ctx context.Context, client client.IngesterClient) (interface{}, error) { | ||
| return client.UserStats(ctx, req) | ||
| }) | ||
| if err != nil { | ||
|
|
@@ -801,7 +824,7 @@ func (d *Distributor) AllUserStats(ctx context.Context) ([]UserIDStats, error) { | |
|
|
||
| req := &client.UserStatsRequest{} | ||
| ctx = user.InjectOrgID(ctx, "1") // fake: ingester insists on having an org ID | ||
| // Not using d.ForAllIngesters(), so we can fail after first error. | ||
| // Not using d.ForReplicationSet(), so we can fail after first error. | ||
| replicationSet, err := d.ingestersRing.GetAll(ring.Read) | ||
| if err != nil { | ||
| return nil, err | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does ingester shuffle sharding on read path depend on shard-by-all-labels being set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it doesn't. I enabled it in this test just because it's how we (and to my knowledge most of users) run Cortex, so to have an integration test which better reflects real setups.