Skip to content
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

Fix sharding behavior for vector matches #5799

Merged
merged 2 commits into from Oct 20, 2022

Conversation

sdufel
Copy link
Contributor

@sdufel sdufel commented Oct 18, 2022

Fixes #5798

When analyzing a query composed of boolean expression with a non-"on" vector match, the current vertical sharding logic is incorrectly scoping to labels in the vector match and changing the semantics of the query.

Example:

foo and without (lbl) bar

Changes

  • Prevents the vertical sharding query analyzer from using labels in a vector match to shard on if the match is done with the ignoring keyword (match On == false)

Verification

  • Manual verification of queries with and without the change; after this modification, queries worked as expected.

I am not clear on if it's actually possible to shard without labels without breaking queries; it's possible that a more appropriate change would be to the shard matcher code in the querier.

@@ -97,7 +97,7 @@ func (a *QueryAnalyzer) Analyze(query string) (QueryAnalysis, error) {
return fmt.Errorf("expressions with %s are not shardable", n.Func.Name)
}
case *parser.BinaryExpr:
if n.VectorMatching != nil {
if n.VectorMatching != nil && n.VectorMatching.On {
Copy link
Contributor

Choose a reason for hiding this comment

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

@sdufel Can you add an unit test case please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After discussing with @fpetkovski, I think we pinned down the issue - a recent change that removed the __name__ label exclusion from sharding caused this regression.

I adjusted the patch to ensure that __name__ isn't used as a shard label for the case of vector matches using the ignoring keyword and added tests to the analyzer.

Sharding by __name__ appears to be fine for aggregations, but it needs special treatment for vector matching.

When analyzing a query composed of boolean expression with a non-"on" vector match,
the current vertical sharding logic is incorrectly scoping to labels in the
vector match and changing the semantics of the query.

Example:
```
foo and without (lbl) bar
```

Signed-off-by: Samuel Dufel <samuel.dufel@shopify.com>
@sdufel sdufel force-pushed the fix-sharding-vector-matching branch from 7caa8bd to 3e4f24f Compare October 19, 2022 16:45
@@ -99,6 +99,9 @@ func (a *QueryAnalyzer) Analyze(query string) (QueryAnalysis, error) {
case *parser.BinaryExpr:
if n.VectorMatching != nil {
shardingLabels := without(n.VectorMatching.MatchingLabels, []string{"le"})
if !n.VectorMatching.On && len(shardingLabels) > 0 {
shardingLabels = append(shardingLabels, "__name__")

Choose a reason for hiding this comment

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

This looks good.

yeya24
yeya24 previously approved these changes Oct 19, 2022
Copy link
Contributor

@yeya24 yeya24 left a comment

Choose a reason for hiding this comment

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

LGTM. cc @fpetkovski for another look

@alanprot
Copy link
Contributor

alanprot commented Oct 20, 2022

I tested this patch on cortex and it indeed fixed the issue.

Do we also need to add this on the analyzeRootExpression?

if n.VectorMatching != nil && n.VectorMatching.On {
shardingLabels := without(n.VectorMatching.MatchingLabels, []string{"le"})
return newShardableByLabels(shardingLabels, n.VectorMatching.On)

As a side note, the https://github.com/prometheus/compliance/tree/main/promql was not able to catch this issue.

I added locally the following query to cover this problem:

QUERY: process_virtual_memory_bytes and ignoring(code) promhttp_metric_handler_requests_total
START: 2022-10-20 02:26:10 +0000 UTC, STOP: 2022-10-20 02:36:10 +0000 UTC, STEP: 10s
RESULT: FAILED: Query returned different results:
  model.Matrix{
- 	(
- 		s"""
- 		process_virtual_memory_bytes{instance="localhost:10000", job="demo"} =>
- 		737312768 @[1666233340]
- 		737312768 @[1666233350]
- 		737312768 @[1666233360]
- 		737312768 @[1666233370]
- 		s"""
- 	),
- 	(
- 		s"""
- 		process_virtual_memory_bytes{instance="localhost:10001", job="demo"} =>
- 		737050624 @[1666233340]
- 		737050624 @[1666233350]
- 		737050624 @[1666233360]
- 		737050624 @[1666233370]
- 		s"""
- 	),
- 	(
- 		s"""
- 		process_virtual_memory_bytes{instance="localhost:10002", job="demo"} =>
- 		737050624 @[1666233340]
- 		737050624 @[1666233350]
- 		737050624 @[1666233360]
- 		737050624 @[1666233370]
- 		s"""
- 	),
  }

alanprot
alanprot previously approved these changes Oct 20, 2022
fpetkovski
fpetkovski previously approved these changes Oct 20, 2022
Copy link
Contributor

@fpetkovski fpetkovski left a comment

Choose a reason for hiding this comment

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

Thanks for the fix, this looks good 👍

@@ -99,6 +99,9 @@ func (a *QueryAnalyzer) Analyze(query string) (QueryAnalysis, error) {
case *parser.BinaryExpr:
if n.VectorMatching != nil {
shardingLabels := without(n.VectorMatching.MatchingLabels, []string{"le"})
if !n.VectorMatching.On && len(shardingLabels) > 0 {
shardingLabels = append(shardingLabels, "__name__")
Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: let's use model.MetricNameLabel.

@@ -142,20 +142,20 @@ sum by (container) (
{
name: "binary expression with without vector matching and grouping",
expression: `sum without (cluster, pod) (http_requests_total{code="400"}) / ignoring (pod) sum without (cluster, pod) (http_requests_total)`,
shardingLabels: []string{"pod", "cluster"},
shardingLabels: []string{"pod", "cluster", "__name__"},
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, just updated these

Signed-off-by: Samuel Dufel <samuel.dufel@shopify.com>
@sdufel sdufel dismissed stale reviews from fpetkovski, alanprot, and yeya24 via a8b39b5 October 20, 2022 15:02
@sdufel
Copy link
Contributor Author

sdufel commented Oct 20, 2022

The analyzeRootExpression func already has a check for VectorMatching.On == true, so I think it's fine as-is.

@yeya24 yeya24 enabled auto-merge (squash) October 20, 2022 15:10
@yeya24 yeya24 merged commit d5744e7 into thanos-io:main Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query Frontend: Vertical sharding without labels is failing to return results
6 participants