@@ -57,7 +57,7 @@ func TestDistributedExecution(t *testing.T) {
57
57
expr : `sum by (pod) (rate(http_requests_total[5m]))` ,
58
58
expected : `
59
59
sum by (pod) (dedup(
60
- remote(sum by (pod, region) (rate(http_requests_total[5m]))),
60
+ remote(sum by (pod, region) (rate(http_requests_total[5m]))),
61
61
remote(sum by (pod, region) (rate(http_requests_total[5m])))))` ,
62
62
},
63
63
{
@@ -158,7 +158,7 @@ sum by (pod) (
158
158
expr : `max by (pod) (sum by (pod) (http_requests_total))` ,
159
159
expected : `
160
160
max by (pod) (
161
- sum by (pod) (
161
+ sum by (pod) (
162
162
dedup(
163
163
remote(sum by (pod, region) (http_requests_total)),
164
164
remote(sum by (pod, region) (http_requests_total))
@@ -194,7 +194,7 @@ max by (pod) (quantile(0.9,
194
194
expr : `label_replace(http_requests_total, "pod", "$1", "instance", "(.*)")` ,
195
195
expected : `
196
196
dedup(
197
- remote(label_replace(http_requests_total, "pod", "$1", "instance", "(.*)")),
197
+ remote(label_replace(http_requests_total, "pod", "$1", "instance", "(.*)")),
198
198
remote(label_replace(http_requests_total, "pod", "$1", "instance", "(.*)"))
199
199
)` ,
200
200
},
@@ -204,7 +204,7 @@ dedup(
204
204
expected : `
205
205
max by (instance) (
206
206
dedup(
207
- remote(max by (instance, region) (label_replace(http_requests_total, "pod", "$1", "instance", "(.*)"))),
207
+ remote(max by (instance, region) (label_replace(http_requests_total, "pod", "$1", "instance", "(.*)"))),
208
208
remote(max by (instance, region) (label_replace(http_requests_total, "pod", "$1", "instance", "(.*)")))
209
209
)
210
210
)` ,
@@ -214,7 +214,7 @@ max by (instance) (
214
214
expr : `max by (location) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)"))` ,
215
215
expected : `
216
216
max by (location) (dedup(
217
- remote(max by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)"))),
217
+ remote(max by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)"))),
218
218
remote(max by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)")))
219
219
))` ,
220
220
},
@@ -237,20 +237,20 @@ max by (location) (dedup(
237
237
sum by (location) (
238
238
dedup(
239
239
remote(sum by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)"))),
240
- remote(sum by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)")))))
240
+ remote(sum by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)")))))
241
241
/ on (location)
242
242
sum by (location) (
243
243
dedup(
244
244
remote(count by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)"))),
245
- remote(count by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)")))))
245
+ remote(count by (location, region) (label_replace(http_requests_total, "zone", "$1", "location", "(.*)")))))
246
246
` ,
247
247
},
248
248
{
249
249
name : "label replace after an aggregation" ,
250
250
expr : `label_replace(max by (location) (http_requests_total), "region", "$1", "location", "(.*)")` ,
251
251
expected : `
252
252
label_replace(max by (location) (dedup(
253
- remote(max by (location, region) (http_requests_total)),
253
+ remote(max by (location, region) (http_requests_total)),
254
254
remote(max by (location, region) (http_requests_total))
255
255
)), "region", "$1", "location", "(.*)")` ,
256
256
expectWarn : true ,
@@ -272,12 +272,12 @@ max by (pod) (
272
272
expr : `sum by (pod) (metric_a) / sum by (pod) (metric_b)` ,
273
273
expected : `
274
274
sum by (pod) (dedup(
275
- remote(sum by (pod, region) (metric_a)),
275
+ remote(sum by (pod, region) (metric_a)),
276
276
remote(sum by (pod, region) (metric_a)))
277
277
)
278
- /
278
+ /
279
279
sum by (pod) (dedup(
280
- remote(sum by (pod, region) (metric_b)),
280
+ remote(sum by (pod, region) (metric_b)),
281
281
remote(sum by (pod, region) (metric_b))
282
282
))` ,
283
283
},
@@ -286,7 +286,7 @@ sum by (pod) (dedup(
286
286
expr : `rate(http_requests_total[2m])` ,
287
287
expected : `
288
288
dedup(
289
- remote(rate(http_requests_total[2m])),
289
+ remote(rate(http_requests_total[2m])),
290
290
remote(rate(http_requests_total[2m]))
291
291
)` ,
292
292
},
@@ -305,7 +305,7 @@ dedup(
305
305
expr : `histogram_quantile(0.5, sum by (le) (rate(coredns_dns_request_duration_seconds_bucket[5m])))` ,
306
306
expected : `
307
307
histogram_quantile(0.5, sum by (le) (dedup(
308
- remote(sum by (le, region) (rate(coredns_dns_request_duration_seconds_bucket[5m]))),
308
+ remote(sum by (le, region) (rate(coredns_dns_request_duration_seconds_bucket[5m]))),
309
309
remote(sum by (le, region) (rate(coredns_dns_request_duration_seconds_bucket[5m])))
310
310
)))` ,
311
311
},
@@ -338,7 +338,7 @@ histogram_quantile(0.5, sum by (le) (dedup(
338
338
name : "binary expression with constant" ,
339
339
expr : `sum by (pod) (rate(http_requests_total[2m]) * 60)` ,
340
340
expected : `sum by (pod) (dedup(
341
- remote(sum by (pod, region) (rate(http_requests_total[2m]) * 60)),
341
+ remote(sum by (pod, region) (rate(http_requests_total[2m]) * 60)),
342
342
remote(sum by (pod, region) (rate(http_requests_total[2m]) * 60))))` ,
343
343
},
344
344
{
@@ -361,7 +361,7 @@ remote(sum by (pod, region) (rate(http_requests_total[2m]) * 60))))`,
361
361
expr : `sum_over_time(max(http_requests_total)[5m:1m])` ,
362
362
expected : `
363
363
sum_over_time(max(dedup(
364
- remote(max by (region) (http_requests_total)) [1969-12-31 23:55:00 +0000 UTC, 1970-01-01 00:00:00 +0000 UTC],
364
+ remote(max by (region) (http_requests_total)) [1969-12-31 23:55:00 +0000 UTC, 1970-01-01 00:00:00 +0000 UTC],
365
365
remote(max by (region) (http_requests_total)) [1969-12-31 23:55:00 +0000 UTC, 1970-01-01 00:00:00 +0000 UTC])
366
366
)[5m:1m])` ,
367
367
},
@@ -415,7 +415,7 @@ count by (cluster) (
415
415
)` ,
416
416
expected : `
417
417
sum by (cluster) (dedup(
418
- remote(count by (cluster, region) (label_replace(up, "ns", "$0", "namespace", ".*") * on (region) group_left (project) label_replace(k8s_cluster_info, "k8s_cluster", "$0", "cluster", ".*"))),
418
+ remote(count by (cluster, region) (label_replace(up, "ns", "$0", "namespace", ".*") * on (region) group_left (project) label_replace(k8s_cluster_info, "k8s_cluster", "$0", "cluster", ".*"))),
419
419
remote(count by (cluster, region) (label_replace(up, "ns", "$0", "namespace", ".*") * on (region) group_left (project) label_replace(k8s_cluster_info, "k8s_cluster", "$0", "cluster", ".*"))))
420
420
)` ,
421
421
},
@@ -548,7 +548,7 @@ dedup(
548
548
expr : `sum_over_time(sum_over_time(metric[1h])[1h:30m])` ,
549
549
expected : `
550
550
dedup(
551
- remote(sum_over_time(sum_over_time(metric[1h])[1h:30m])),
551
+ remote(sum_over_time(sum_over_time(metric[1h])[1h:30m])),
552
552
remote(sum_over_time(sum_over_time(metric[1h])[1h:30m])) [1970-01-01 08:00:00 +0000 UTC, 1970-01-01 12:00:00 +0000 UTC]
553
553
)` ,
554
554
},
@@ -606,7 +606,7 @@ dedup(
606
606
expr : `sum(metric @ 25200)` ,
607
607
expected : `
608
608
sum(dedup(
609
- remote(sum by (region) (metric @ 25200.000)),
609
+ remote(sum by (region) (metric @ 25200.000)),
610
610
remote(sum by (region) (metric @ 25200.000)) [1970-01-01 06:00:00 +0000 UTC, 1970-01-01 12:00:00 +0000 UTC]
611
611
))` ,
612
612
},
@@ -685,7 +685,7 @@ func TestDistributedExecutionPruningByTime(t *testing.T) {
685
685
expected : `
686
686
sum(
687
687
dedup(
688
- remote(sum by (region) (metric)) [1970-01-01 06:00:00 +0000 UTC, 1970-01-01 06:00:00 +0000 UTC],
688
+ remote(sum by (region) (metric)) [1970-01-01 06:00:00 +0000 UTC, 1970-01-01 06:00:00 +0000 UTC],
689
689
remote(sum by (region) (metric)) [1970-01-01 06:00:00 +0000 UTC, 1970-01-01 06:00:00 +0000 UTC]
690
690
)
691
691
)` ,
@@ -713,14 +713,74 @@ sum(
713
713
}
714
714
}
715
715
716
+ func TestDistributedExecutionPruningByLabelset (t * testing.T ) {
717
+ cases := []struct {
718
+ name string
719
+ expr string
720
+ expected string
721
+ }{
722
+ {
723
+ name : "querying by labelsets restricts to partition that matches that labelset" ,
724
+ expr : `sum by (pod) (rate(http_requests_total{region="west"}[2m]))` ,
725
+ expected : `sum by (pod) (dedup(remote(sum by (datacenter, pod) (rate(http_requests_total{region="west"}[2m])))))` ,
726
+ },
727
+ {
728
+ name : "querying by labelsets restricts to partition that matches that labelset" ,
729
+ expr : `sum by (pod) (rate(http_requests_total{region="east"}[2m]))` ,
730
+ expected : `
731
+ sum by (pod) (dedup(
732
+ remote(sum by (datacenter, pod) (rate(http_requests_total{region="east"}[2m]))),
733
+ remote(sum by (datacenter, pod) (rate(http_requests_total{region="east"}[2m])))
734
+ ))` ,
735
+ },
736
+ }
737
+
738
+ for _ , tcase := range cases {
739
+ t .Run (tcase .name , func (t * testing.T ) {
740
+ // We are partitioned by datacenter but also have a "region" label that we can target
741
+ engines := []api.RemoteEngine {
742
+ newEngineMockWithExplicitPartition (
743
+ math .MinInt64 ,
744
+ math .MaxInt64 ,
745
+ []labels.Labels {labels .FromStrings ("region" , "east" , "datacenter" , "east-1" )},
746
+ []labels.Labels {labels .FromStrings ("datacenter" , "east-1" )},
747
+ ),
748
+ newEngineMockWithExplicitPartition (
749
+ math .MinInt64 ,
750
+ math .MaxInt64 ,
751
+ []labels.Labels {labels .FromStrings ("region" , "east" , "datacenter" , "east-2" )},
752
+ []labels.Labels {labels .FromStrings ("datacenter" , "east-2" )},
753
+ ),
754
+ newEngineMockWithExplicitPartition (
755
+ math .MinInt64 ,
756
+ math .MaxInt64 ,
757
+ []labels.Labels {labels .FromStrings ("region" , "west" , "datacenter" , "west-1" )},
758
+ []labels.Labels {labels .FromStrings ("datacenter" , "west-1" )},
759
+ ),
760
+ }
761
+ optimizers := []Optimizer {
762
+ DistributedExecutionOptimizer {Endpoints : api .NewStaticEndpoints (engines )},
763
+ }
764
+
765
+ expr , err := parser .ParseExpr (tcase .expr )
766
+ testutil .Ok (t , err )
767
+
768
+ plan := NewFromAST (expr , & query.Options {Start : time .Unix (0 , 0 ), End : time .Unix (0 , 0 )}, PlanOptions {})
769
+ optimizedPlan , _ := plan .Optimize (optimizers )
770
+ expectedPlan := cleanUp (replacements , tcase .expected )
771
+ testutil .Equals (t , expectedPlan , renderExprTree (optimizedPlan .Root ()))
772
+ })
773
+ }
774
+ }
775
+
716
776
func TestDistributedExecutionClonesNodes (t * testing.T ) {
717
777
var (
718
778
start = time .Unix (0 , 0 )
719
779
end = time .Unix (0 , 0 ).Add (6 * time .Hour )
720
780
step = time .Second
721
781
expected = `
722
782
sum(dedup(
723
- remote(sum by (region) (metric{region="east"})),
783
+ remote(sum by (region) (metric{region="east"})),
724
784
remote(sum by (region) (metric{region="east"}))
725
785
))`
726
786
)
@@ -759,9 +819,10 @@ sum(dedup(
759
819
760
820
type engineMock struct {
761
821
api.RemoteEngine
762
- minT int64
763
- maxT int64
764
- labelSets []labels.Labels
822
+ minT int64
823
+ maxT int64
824
+ labelSets []labels.Labels
825
+ partitionLabelSets []labels.Labels
765
826
}
766
827
767
828
func (e engineMock ) MaxT () int64 {
@@ -776,6 +837,14 @@ func (e engineMock) LabelSets() []labels.Labels {
776
837
return e .labelSets
777
838
}
778
839
840
+ func (e engineMock ) PartitionLabelSets () []labels.Labels {
841
+ return e .partitionLabelSets
842
+ }
843
+
779
844
func newEngineMock (mint , maxt int64 , labelSets []labels.Labels ) * engineMock {
780
- return & engineMock {minT : mint , maxT : maxt , labelSets : labelSets }
845
+ return & engineMock {minT : mint , maxT : maxt , labelSets : labelSets , partitionLabelSets : labelSets }
846
+ }
847
+
848
+ func newEngineMockWithExplicitPartition (mint , maxt int64 , labelSets , partitionLabelSets []labels.Labels ) * engineMock {
849
+ return & engineMock {minT : mint , maxT : maxt , labelSets : labelSets , partitionLabelSets : partitionLabelSets }
781
850
}
0 commit comments