From 42e580952f87f3af8153c501066a577c462535a6 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 17:50:17 -0400 Subject: [PATCH 01/25] feat(asap-tools): use whole-second spatial workloads --- .../accelerated-random-workload-eval.md | 17 +++++++------ .../datasets/fake_metric/random_workloads.py | 4 ++-- .../seed-862/workload-01.json | 24 +++++++++---------- .../seed-862/workload-02.json | 24 +++++++++---------- .../seed-862/workload-03.json | 24 +++++++++---------- .../seed-862/workload-04.json | 24 +++++++++---------- .../seed-862/workload-05.json | 24 +++++++++---------- .../seed-862/workload-06.json | 24 +++++++++---------- .../seed-862/workload-07.json | 24 +++++++++---------- .../seed-862/workload-08.json | 24 +++++++++---------- .../seed-862/workload-09.json | 24 +++++++++---------- .../seed-862/workload-10.json | 24 +++++++++---------- .../tests/test_random_workloads.py | 7 ++++++ 13 files changed, 137 insertions(+), 131 deletions(-) diff --git a/.design_docs/accelerated-random-workload-eval.md b/.design_docs/accelerated-random-workload-eval.md index e8983734..51316023 100644 --- a/.design_docs/accelerated-random-workload-eval.md +++ b/.design_docs/accelerated-random-workload-eval.md @@ -51,20 +51,19 @@ unbounded. | Lookback `W` | Allowed repeat intervals `T` | | ---: | ---: | -| 100 ms | 1 s | +| 1 s | 1 s | | 1 min | 1 s, 2 s | | 5 min | 5 s, 10 s | | 10 min | 10 s, 20 s | | 20 min | 30 s, 60 s | The maximum accelerated backfill is therefore only 20 minutes of event-time -history. The first 100 ms class is for spatial queries; temporal queries use -the 1--20 minute classes. The spatial class targets a 100 ms repetition -interval. Current exact-MV support is whole-second only, so this class is -gated on [#876](https://github.com/ProjectASAP/ASAPQuery/issues/876), which -adds millisecond interval metadata, `DateTime64` bucket flooring and edge -handling, a sub-second query schedule, and raw-versus-MV equivalence tests. -This is a limitation of the current baseline generator, not of ClickHouse. +history. The first 1 s class is for spatial queries; temporal queries use the +1--20 minute classes. Scraping remains every 100 ms, so each spatial query +still consumes ten samples per leaf series. Its whole-second repetition and +lookback are compatible with the current exact-MV arm; it is not gated on +[#876](https://github.com/ProjectASAP/ASAPQuery/issues/876). That issue is +needed only for a future sub-second query/MV schedule. ## Query-template catalogue @@ -119,7 +118,7 @@ first pilot workload. ### Quantile -For the 100 ms spatial class, PromQL has exact grouped semantics: +For the 1 s spatial class, PromQL has exact grouped semantics: ```promql quantile by (G) (phi, data) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index 1029fc80..b6e82452 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -19,8 +19,8 @@ ACCURACY_SLA = 0.95 SECOND_MS = 1_000 MINUTE_MS = 60 * SECOND_MS -SPATIAL_LOOKBACK_MS = 100 -SPATIAL_INTERVAL_MS = 100 +SPATIAL_LOOKBACK_MS = SECOND_MS +SPATIAL_INTERVAL_MS = SECOND_MS LABEL_HIERARCHY = ( ("region", 4, None), ("service", 5, "region"), diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index 0e3f9250..b2325536 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -87,8 +87,8 @@ "job" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.99, data)", @@ -102,8 +102,8 @@ "job" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.99 } @@ -116,8 +116,8 @@ "region" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.95, data)", @@ -129,8 +129,8 @@ "region" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -145,8 +145,8 @@ "job" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.75, data)", @@ -160,8 +160,8 @@ "job" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index 171e2d0a..f96c214d 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -85,8 +85,8 @@ "region" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.75, data)", @@ -98,8 +98,8 @@ "region" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -113,8 +113,8 @@ "service" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.95, data)", @@ -127,8 +127,8 @@ "service" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -143,8 +143,8 @@ "job" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.99, data)", @@ -158,8 +158,8 @@ "job" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.99 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index 5d93cf32..b14bc425 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -86,8 +86,8 @@ "service" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.95, data)", @@ -100,8 +100,8 @@ "service" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -115,8 +115,8 @@ "service" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.90, data)", @@ -129,8 +129,8 @@ "service" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.9 } @@ -145,8 +145,8 @@ "job" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.90, data)", @@ -160,8 +160,8 @@ "job" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index 2bf9ab31..6fbee29f 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -85,8 +85,8 @@ "region" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.75, data)", @@ -98,8 +98,8 @@ "region" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -113,8 +113,8 @@ "service" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.75, data)", @@ -127,8 +127,8 @@ "service" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -141,8 +141,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.95, data)", @@ -154,8 +154,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index f12afc78..eed23e94 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -86,8 +86,8 @@ "service" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.99, data)", @@ -100,8 +100,8 @@ "service" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.99 } @@ -116,8 +116,8 @@ "job" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.50, data)", @@ -131,8 +131,8 @@ "job" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.5 } @@ -145,8 +145,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.90, data)", @@ -158,8 +158,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index ae2ad018..929b4563 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -87,8 +87,8 @@ "job" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.50, data)", @@ -102,8 +102,8 @@ "job" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.5 } @@ -117,8 +117,8 @@ "service" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.50, data)", @@ -131,8 +131,8 @@ "service" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.5 } @@ -145,8 +145,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.90, data)", @@ -158,8 +158,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index 5d7053cf..6a38b67f 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -87,8 +87,8 @@ "job" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.99, data)", @@ -102,8 +102,8 @@ "job" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.99 } @@ -118,8 +118,8 @@ "job" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.95, data)", @@ -133,8 +133,8 @@ "job" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -147,8 +147,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.50, data)", @@ -160,8 +160,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.5 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index dd6f1df6..7686e574 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -86,8 +86,8 @@ "service" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.75, data)", @@ -100,8 +100,8 @@ "service" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -115,8 +115,8 @@ "service" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.95, data)", @@ -129,8 +129,8 @@ "service" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -143,8 +143,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.95, data)", @@ -156,8 +156,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index f1c095f4..e4736d8e 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -87,8 +87,8 @@ "job" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.75, data)", @@ -102,8 +102,8 @@ "job" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -118,8 +118,8 @@ "job" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, "promql": "quantile by (region, service, job) (0.95, data)", @@ -133,8 +133,8 @@ "job" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.95 } @@ -148,8 +148,8 @@ "service" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.75, data)", @@ -162,8 +162,8 @@ "service" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index d93c5ac3..9f6ad692 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -86,8 +86,8 @@ "service" ], "id": "q03-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, "promql": "quantile by (region, service) (0.99, data)", @@ -100,8 +100,8 @@ "service" ], "id": "q03-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.99 } @@ -114,8 +114,8 @@ "region" ], "id": "q04-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.75, data)", @@ -127,8 +127,8 @@ "region" ], "id": "q04-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.75 } @@ -141,8 +141,8 @@ "region" ], "id": "q05-quantile", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, "promql": "quantile by (region) (0.90, data)", @@ -154,8 +154,8 @@ "region" ], "id": "q05-quantile/rqe", - "interval_ms": 100, - "lookback_ms": 100, + "interval_ms": 1000, + "lookback_ms": 1000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index 1cbad9f7..8f939075 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -53,6 +53,13 @@ def test_visible_query_outputs_stay_bounded(self): self.assertEqual(query["output_series_upper_bound"], expected) self.assertLessEqual(query["output_series_upper_bound"], 200) + def test_spatial_quantiles_repeat_at_whole_second_cadence(self): + for workload in workloads.generate_workloads(seed=4): + for query in workload["queries"]: + if query["rqes"][0]["capability"] == "quantile": + self.assertEqual(query["lookback_ms"], workloads.SECOND_MS) + self.assertEqual(query["interval_ms"], workloads.SECOND_MS) + def test_workloads_do_not_repeat_an_atomic_rqe(self): for workload in workloads.generate_workloads(seed=1): keys = [] From fd17a1b0f4dfc7ec7e2ef9f3ff15b5a6127ee9ea Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 17:58:32 -0400 Subject: [PATCH 02/25] feat(asap-tools): declare random workload data facts --- .../accelerated-random-workload-eval.md | 7 +++ .../fake_metric/random_workload_artifacts.py | 15 +++++- .../datasets/fake_metric/random_workloads.py | 53 +++++++++++++++++++ .../seed-862/workload-01.json | 36 +++++++++++++ .../seed-862/workload-02.json | 36 +++++++++++++ .../seed-862/workload-03.json | 36 +++++++++++++ .../seed-862/workload-04.json | 36 +++++++++++++ .../seed-862/workload-05.json | 36 +++++++++++++ .../seed-862/workload-06.json | 36 +++++++++++++ .../seed-862/workload-07.json | 36 +++++++++++++ .../seed-862/workload-08.json | 36 +++++++++++++ .../seed-862/workload-09.json | 36 +++++++++++++ .../seed-862/workload-10.json | 36 +++++++++++++ .../tests/test_random_workload_artifacts.py | 4 +- .../tests/test_random_workloads.py | 10 ++++ 15 files changed, 447 insertions(+), 2 deletions(-) diff --git a/.design_docs/accelerated-random-workload-eval.md b/.design_docs/accelerated-random-workload-eval.md index 51316023..73071b89 100644 --- a/.design_docs/accelerated-random-workload-eval.md +++ b/.design_docs/accelerated-random-workload-eval.md @@ -181,6 +181,13 @@ The manifest also contains the label hierarchy, cardinalities of every legal grouping, value/key distribution facts, feeder seed, and support class (`common-promql`, `counter-gated-promql`, or `sql-only`). +The `data_facts` contract fixes a 100 ms scrape cadence and 20-minute +backfill, a deterministic Zipf-like ranking of the 10,000 leaf series, a +rank-scaled gauge and monotonic counter (no resets), plus a 10,000-ID user +universe. Each leaf rotates through 1,000 deterministically assigned IDs; +the pools overlap across leaves. The eventual feeder and every baseline +adapter must implement these facts rather than choose their own distributions. + Sampling is constrained rather than purely independent: - exactly ten atomic queries per workload and no binary queries; diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index bc7db547..2854e0a9 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -42,6 +42,8 @@ def render(workload): labels = [label["name"] for label in workload["labels"]] queries = workload["queries"] return { + "workload_id": workload["id"], + "data_facts": workload["data_facts"], "queries": queries, "promql_planner": { "metrics": [{"metric": metric, "labels": labels} for metric in PROMQL_METRICS], @@ -69,7 +71,18 @@ def main(): path.write_text(yaml.safe_dump(rendered[name], sort_keys=False)) print(path) schedule = args.out / "queries.json" - schedule.write_text(json.dumps(rendered["queries"], indent=2, sort_keys=True) + "\n") + schedule.write_text( + json.dumps( + { + "workload_id": rendered["workload_id"], + "data_facts": rendered["data_facts"], + "queries": rendered["queries"], + }, + indent=2, + sort_keys=True, + ) + + "\n" + ) print(schedule) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index b6e82452..909ba758 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -45,6 +45,11 @@ ) QUANTILES = (0.50, 0.75, 0.90, 0.95, 0.99) TOPK_VALUES = (4, 8) +BACKFILL_HISTORY_MS = 20 * MINUTE_MS +LEAF_SERIES_COUNT = math.prod(LABEL_CARDINALITIES.values()) +ZIPF_EXPONENT = 1.1 +USER_ID_UNIVERSE_SIZE = 10_000 +USER_IDS_PER_LEAF = 1_000 def duration(milliseconds): @@ -61,6 +66,43 @@ def choose_temporal_time(rng): return lookback_ms, rng.choice(intervals) +def workload_data_facts(seed): + """Return the feeder contract shared by every workload from one seed.""" + return { + "feeder_seed": seed, + "scrape_interval_ms": SPATIAL_LOOKBACK_MS // 10, + "backfill_history_ms": BACKFILL_HISTORY_MS, + "series": { + "leaf_count": LEAF_SERIES_COUNT, + "ranking": { + "kind": "deterministic_zipf_like", + "exponent": ZIPF_EXPONENT, + "rank_scope": "leaf_series", + }, + }, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [0.0, 1_000.0], + "value_shape": "rank_scaled_deterministic_variation", + }, + "data_total": { + "kind": "counter", + "increment_shape": "rank_scaled_positive_deterministic", + "resets": "none", + }, + }, + "events": { + "table": "events", + "time_column": "ts", + "distinct_key": "user_id", + "user_id_universe_size": USER_ID_UNIVERSE_SIZE, + "user_ids_per_leaf": USER_IDS_PER_LEAF, + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + }, + } + + def query( query_id, capability, @@ -231,6 +273,7 @@ def generate_workload(seed, index): "seed": seed, "labels": METRIC_LABELS, "samples_per_sec_per_series": SAMPLES_PER_SEC_PER_SERIES, + "data_facts": workload_data_facts(seed), "queries": queries, } validate_workload(workload) @@ -240,6 +283,16 @@ def generate_workload(seed, index): def validate_workload(workload): """Reject manifests that violate the experiment's stable public contract.""" queries = workload["queries"] + data_facts = workload["data_facts"] + if data_facts["scrape_interval_ms"] != SECOND_MS // SAMPLES_PER_SEC_PER_SERIES: + raise ValueError("data facts must declare the 100 ms scrape interval") + if data_facts["series"]["leaf_count"] != LEAF_SERIES_COUNT: + raise ValueError("data facts must declare every leaf series") + if data_facts["metrics"]["data_total"]["resets"] != "none": + raise ValueError("the pilot counter contract must be monotonic") + events = data_facts["events"] + if not 0 < events["user_ids_per_leaf"] <= events["user_id_universe_size"]: + raise ValueError("distinct user pools must fit in the declared universe") if len(queries) != QUERIES_PER_WORKLOAD: raise ValueError(f"a workload must contain exactly {QUERIES_PER_WORKLOAD} queries") if len({query["id"] for query in queries}) != len(queries): diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index b2325536..12b03cd3 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-01", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index f96c214d..8a850796 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-02", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index b14bc425..8bdf9a46 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-03", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index 6fbee29f..ea5b7387 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-04", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index eed23e94..06dbba03 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-05", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index 929b4563..bb051de7 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-06", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index 6a38b67f..d4bd033a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-07", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index 7686e574..3c4da540 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-08", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index e4736d8e..241118d3 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-09", "labels": [ { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index 9f6ad692..fa7485bc 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -1,4 +1,40 @@ { + "data_facts": { + "backfill_history_ms": 1200000, + "events": { + "assignment": "deterministic_rotating_pool_with_cross_leaf_overlap", + "distinct_key": "user_id", + "table": "events", + "time_column": "ts", + "user_id_universe_size": 10000, + "user_ids_per_leaf": 1000 + }, + "feeder_seed": 862, + "metrics": { + "data": { + "kind": "gauge", + "value_range": [ + 0.0, + 1000.0 + ], + "value_shape": "rank_scaled_deterministic_variation" + }, + "data_total": { + "increment_shape": "rank_scaled_positive_deterministic", + "kind": "counter", + "resets": "none" + } + }, + "scrape_interval_ms": 100, + "series": { + "leaf_count": 10000, + "ranking": { + "exponent": 1.1, + "kind": "deterministic_zipf_like", + "rank_scope": "leaf_series" + } + } + }, "id": "workload-10", "labels": [ { diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index a3f21f93..51a1cf32 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -13,7 +13,8 @@ class RenderArtifactsTest(unittest.TestCase): def test_promql_input_groups_non_sql_queries_by_repeat_interval(self): - rendered = artifacts.render(workloads.generate_workloads(seed=862)[0]) + workload = workloads.generate_workloads(seed=862)[0] + rendered = artifacts.render(workload) planner = rendered["promql_planner"] expected = [q for q in rendered["queries"] if q["promql"]] @@ -24,6 +25,7 @@ def test_promql_input_groups_non_sql_queries_by_repeat_interval(self): {tuple(metric["labels"]) for metric in planner["metrics"]}, {("region", "service", "job", "label_0")}, ) + self.assertEqual(rendered["data_facts"], workload["data_facts"]) for group in planner["query_groups"]: self.assertTrue(all(query["interval_ms"] == group["repetition_delay_ms"] for query in expected if query["promql"] in group["queries"])) diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index 8f939075..db4a9a52 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -60,6 +60,16 @@ def test_spatial_quantiles_repeat_at_whole_second_cadence(self): self.assertEqual(query["lookback_ms"], workloads.SECOND_MS) self.assertEqual(query["interval_ms"], workloads.SECOND_MS) + def test_manifest_declares_deterministic_feeder_facts(self): + facts = workloads.generate_workloads(seed=4)[0]["data_facts"] + + self.assertEqual(facts["scrape_interval_ms"], 100) + self.assertEqual(facts["series"]["leaf_count"], 10_000) + self.assertEqual(facts["series"]["ranking"]["exponent"], 1.1) + self.assertEqual(facts["metrics"]["data_total"]["resets"], "none") + self.assertEqual(facts["events"]["user_id_universe_size"], 10_000) + self.assertEqual(facts["events"]["user_ids_per_leaf"], 1_000) + def test_workloads_do_not_repeat_an_atomic_rqe(self): for workload in workloads.generate_workloads(seed=1): keys = [] From c6df33255e6bb6b5f2bd1438a9cd8395bfe0caa4 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:05:26 -0400 Subject: [PATCH 03/25] feat(paced-feeder): render manifest-driven event pools --- .../accelerated-random-workload-eval.md | 2 +- .../data-sources/paced-feeder/README.md | 5 + .../data-sources/paced-feeder/src/records.rs | 134 ++++++++++++++++-- .../fake_metric/random_workload_artifacts.py | 60 ++++++++ .../datasets/fake_metric/random_workloads.py | 4 +- .../seed-862/workload-01.json | 7 +- .../seed-862/workload-02.json | 7 +- .../seed-862/workload-03.json | 7 +- .../seed-862/workload-04.json | 7 +- .../seed-862/workload-05.json | 7 +- .../seed-862/workload-06.json | 7 +- .../seed-862/workload-07.json | 7 +- .../seed-862/workload-08.json | 7 +- .../seed-862/workload-09.json | 7 +- .../seed-862/workload-10.json | 7 +- .../tests/test_random_workload_artifacts.py | 13 ++ .../tests/test_random_workloads.py | 1 + 17 files changed, 227 insertions(+), 62 deletions(-) diff --git a/.design_docs/accelerated-random-workload-eval.md b/.design_docs/accelerated-random-workload-eval.md index 73071b89..be3764f2 100644 --- a/.design_docs/accelerated-random-workload-eval.md +++ b/.design_docs/accelerated-random-workload-eval.md @@ -183,7 +183,7 @@ grouping, value/key distribution facts, feeder seed, and support class The `data_facts` contract fixes a 100 ms scrape cadence and 20-minute backfill, a deterministic Zipf-like ranking of the 10,000 leaf series, a -rank-scaled gauge and monotonic counter (no resets), plus a 10,000-ID user +rank-scaled Pareto gauge and monotonic counter (no resets), plus a 10,000-ID user universe. Each leaf rotates through 1,000 deterministically assigned IDs; the pools overlap across leaves. The eventual feeder and every baseline adapter must implement these facts rather than choose their own distributions. diff --git a/asap-tools/data-sources/paced-feeder/README.md b/asap-tools/data-sources/paced-feeder/README.md index ab41bd70..39d23e10 100644 --- a/asap-tools/data-sources/paced-feeder/README.md +++ b/asap-tools/data-sources/paced-feeder/README.md @@ -97,6 +97,11 @@ name), `n` and the draw, so records match sketch-bench's `label_shares()` `endpoint="3.17"`). - **Keys** (`zipf` θ over `keys`): the key of Zipf rank `r` is `r`, so key 0 is the most frequent. +- **Rotating per-series pool** (`{"rotating_pool": {"universe_keys": U, + "keys_per_series": K}}`): records enumerate every label combination evenly; + each combination cycles through a deterministic K-key pool in the U-key + universe. Pool starts are seeded per combination, so pools overlap while + each leaf has exactly K possible keys. - **Burst**: with probability `share` a record is a burst record: its `label` is `value` (a child index for a child label) and its key is uniform over `keys` burst keys numbered after the background keys (`1000000` to diff --git a/asap-tools/data-sources/paced-feeder/src/records.rs b/asap-tools/data-sources/paced-feeder/src/records.rs index 7075d17b..2e15c9ef 100644 --- a/asap-tools/data-sources/paced-feeder/src/records.rs +++ b/asap-tools/data-sources/paced-feeder/src/records.rs @@ -74,11 +74,19 @@ struct FieldSpec { zipf: Option, keys: Option, burst: Option, + rotating_pool: Option, pareto: Option, scaled_by: Option, anomaly: Option, } +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct RotatingPoolSpec { + universe_keys: u64, + keys_per_series: u64, +} + #[derive(Deserialize)] #[serde(deny_unknown_fields)] struct BurstSpec { @@ -169,6 +177,10 @@ enum Field { zipf: Zipf, keys: u64, }, + RotatingPool { + universe_keys: u64, + keys_per_series: u64, + }, Pareto { shape: f64, /// The `scaled_by` label and each of its values' factor. @@ -190,6 +202,8 @@ pub struct RecordMetric { /// Value field names, in name order. pub fields: Vec, field_kinds: Vec, + round_robin_series: bool, + series_count: u64, pub burst: Option, pub records_per_sec: u64, seed: u64, @@ -258,6 +272,7 @@ impl RecordMetric { zipf: Some(theta), keys: Some(keys), burst: field_burst, + rotating_pool: None, pareto: None, scaled_by: None, anomaly: None, @@ -301,6 +316,33 @@ impl RecordMetric { zipf: None, keys: None, burst: None, + rotating_pool: Some(pool), + pareto: None, + scaled_by: None, + anomaly: None, + } => { + ensure!( + pool.universe_keys > 0 && pool.keys_per_series > 0, + "value `{field}`: rotating pool sizes must be positive" + ); + ensure!( + pool.keys_per_series <= pool.universe_keys, + "value `{field}`: rotating pool must fit in its universe" + ); + ensure!( + pool.universe_keys <= MAX_KEY, + "value `{field}`: rotating pool keys must be ≤ 2^53" + ); + Field::RotatingPool { + universe_keys: pool.universe_keys, + keys_per_series: pool.keys_per_series, + } + } + FieldSpec { + zipf: None, + keys: None, + burst: None, + rotating_pool: None, pareto: Some(shape), scaled_by, anomaly, @@ -346,6 +388,19 @@ impl RecordMetric { } let records_per_sec = records_per_sec.unwrap_or(spec.records_per_sec); ensure!(records_per_sec > 0, "records per second must be positive"); + let series_count = labels + .iter() + .try_fold(1u64, |count, label| count.checked_mul(label.cardinality)) + .context("too many record label combinations")?; + let round_robin_series = field_kinds + .iter() + .any(|field| matches!(field, Field::RotatingPool { .. })); + if round_robin_series { + ensure!( + records_per_sec % series_count == 0, + "records per second must be a multiple of record label combinations for rotating pools" + ); + } Ok(Self { name: name.to_string(), labels, @@ -354,6 +409,8 @@ impl RecordMetric { label_zipfs, fields, field_kinds, + round_robin_series, + series_count, burst, records_per_sec, seed: splitmix64(seed ^ fnv1a(name)), @@ -369,15 +426,33 @@ impl RecordMetric { let stream = num_labels + self.fields.len() as u64; u(stream) <= b.share }); - for (i, zipf) in self.label_zipfs.iter().enumerate() { - let child = match burst { - Some(b) if b.label == i => b.value, - _ => zipf.draw(u(i as u64)), - }; - labels[i] = match self.parents[i] { - None => child, - Some(p) => u64::from(labels[p]) * self.labels[i].cardinality + child, - } as u32; + if self.round_robin_series { + let mut series = index % self.series_count; + let mut children = vec![0u64; self.labels.len()]; + for i in (0..self.labels.len()).rev() { + let cardinality = self.labels[i].cardinality; + children[i] = series % cardinality; + series /= cardinality; + } + for i in 0..self.labels.len() { + let cardinality = self.labels[i].cardinality; + let child = children[i]; + labels[i] = match self.parents[i] { + None => child, + Some(p) => u64::from(labels[p]) * cardinality + child, + } as u32; + } + } else { + for (i, zipf) in self.label_zipfs.iter().enumerate() { + let child = match burst { + Some(b) if b.label == i => b.value, + _ => zipf.draw(u(i as u64)), + }; + labels[i] = match self.parents[i] { + None => child, + Some(p) => u64::from(labels[p]) * self.labels[i].cardinality + child, + } as u32; + } } for (j, kind) in self.field_kinds.iter().enumerate() { let u = u(num_labels + j as u64); @@ -389,6 +464,15 @@ impl RecordMetric { } _ => zipf.draw(u) as f64, }, + Field::RotatingPool { + universe_keys, + keys_per_series, + } => { + let series = index % self.series_count; + let pool_start = splitmix64(self.seed ^ series) % universe_keys; + let rotation = (index / self.series_count) % keys_per_series; + ((pool_start + rotation) % universe_keys) as f64 + } Field::Pareto { shape, scaled_by, @@ -637,6 +721,38 @@ pub mod tests { RecordMetric::from_table(name, spec, None, 42).unwrap() } + #[test] + fn rotating_pool_cycles_each_leafs_overlapping_key_pool() { + let spec = json!({ + "type": "records", "records_per_sec": 12, + "labels": [ + {"name": "region", "cardinality": 2, "skew": 0.0}, + {"name": "leaf", "cardinality": 3, "child_of": "region", "skew": 0.0} + ], + "values": {"user_id": {"rotating_pool": { + "universe_keys": 10, "keys_per_series": 4 + }}} + }); + let metric = metric("events", &spec); + let rows = records(&metric, 24); + + for (index, (labels, _)) in rows.iter().enumerate() { + let series = index as u64 % 6; + assert_eq!(labels[0], (series / 3) as u32); + assert_eq!(labels[1], series as u32); + } + for series in 0..6 { + let values: HashSet = rows + .iter() + .skip(series) + .step_by(6) + .map(|(_, values)| values[0] as u64) + .collect(); + assert_eq!(values.len(), 4); + assert!(values.iter().all(|&value| value < 10)); + } + } + /// Records `0..n` as (label value indices, values). fn records(m: &RecordMetric, n: u64) -> Vec<(Vec, Vec)> { (0..n) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index 2854e0a9..e3aaab0b 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -19,6 +19,62 @@ } +def paced_feeder_table(workload): + """Render the manifest's data facts as a paced-feeder workload table.""" + facts = workload["data_facts"] + labels = workload["labels"] + series = facts["series"] + samples_per_sec = workload["samples_per_sec_per_series"] + return { + "workloads": [ + { + "e2e": { + "metrics": { + "data": { + "type": "gauge", + "labels": labels, + "samples_per_sec_per_series": samples_per_sec, + "values": { + "value": { + "zipf": series["ranking"]["exponent"], + "keys": series["leaf_count"], + }, + "dist": { + "pareto": facts["metrics"]["data"]["pareto_shape"] + }, + }, + }, + "data_total": { + "type": "counter", + "labels": labels, + "samples_per_sec_per_series": samples_per_sec, + "values": { + "increment": { + "zipf": series["ranking"]["exponent"], + "keys": series["leaf_count"], + } + }, + }, + "events": { + "type": "records", + "records_per_sec": series["leaf_count"] * samples_per_sec, + "labels": [{**label, "skew": 0.0} for label in labels], + "values": { + facts["events"]["distinct_key"]: { + "rotating_pool": { + "universe_keys": facts["events"]["user_id_universe_size"], + "keys_per_series": facts["events"]["user_ids_per_leaf"], + } + } + }, + }, + } + } + } + ] + } + + def query_groups(queries, query_key): """Group rendered query text by its fixed repetition interval.""" grouped = defaultdict(list) @@ -45,6 +101,7 @@ def render(workload): "workload_id": workload["id"], "data_facts": workload["data_facts"], "queries": queries, + "paced_feeder_table": paced_feeder_table(workload), "promql_planner": { "metrics": [{"metric": metric, "labels": labels} for metric in PROMQL_METRICS], "query_groups": query_groups(queries, "promql"), @@ -84,6 +141,9 @@ def main(): + "\n" ) print(schedule) + table = args.out / "paced_feeder_table.json" + table.write_text(json.dumps(rendered["paced_feeder_table"], indent=2, sort_keys=True) + "\n") + print(table) if __name__ == "__main__": diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index 909ba758..b903f7da 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -83,8 +83,8 @@ def workload_data_facts(seed): "metrics": { "data": { "kind": "gauge", - "value_range": [0.0, 1_000.0], - "value_shape": "rank_scaled_deterministic_variation", + "value_shape": "rank_scaled_pareto", + "pareto_shape": 2.0, }, "data_total": { "kind": "counter", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index 12b03cd3..0b879d3a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index 8a850796..2f009590 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index 8bdf9a46..d12aa198 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index ea5b7387..5cbf65ff 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index 06dbba03..f99ff415 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index bb051de7..04787070 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index d4bd033a..5c0bcfc7 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index 3c4da540..df564e7e 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index 241118d3..8093c52a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index fa7485bc..2bc74b80 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -13,11 +13,8 @@ "metrics": { "data": { "kind": "gauge", - "value_range": [ - 0.0, - 1000.0 - ], - "value_shape": "rank_scaled_deterministic_variation" + "pareto_shape": 2.0, + "value_shape": "rank_scaled_pareto" }, "data_total": { "increment_shape": "rank_scaled_positive_deterministic", diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 51a1cf32..9471fb72 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -38,6 +38,19 @@ def test_sql_input_contains_only_sql_queries_and_their_table_schema(self): sql = [query for group in rendered["sql_planner"]["query_groups"] for query in group["queries"]] self.assertTrue(all("COUNT(DISTINCT user_id)" in query for query in sql)) + def test_paced_feeder_table_preserves_all_manifest_data_facts(self): + table = artifacts.paced_feeder_table(workloads.generate_workloads(seed=862)[0]) + metrics = table["workloads"][0]["e2e"]["metrics"] + + self.assertEqual(metrics["data"]["samples_per_sec_per_series"], 10) + self.assertEqual(metrics["data"]["values"]["value"]["keys"], 10_000) + self.assertEqual(metrics["data_total"]["type"], "counter") + self.assertEqual(metrics["events"]["records_per_sec"], 100_000) + self.assertEqual( + metrics["events"]["values"]["user_id"]["rotating_pool"], + {"universe_keys": 10_000, "keys_per_series": 1_000}, + ) + if __name__ == "__main__": unittest.main() diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index db4a9a52..c064f1ef 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -66,6 +66,7 @@ def test_manifest_declares_deterministic_feeder_facts(self): self.assertEqual(facts["scrape_interval_ms"], 100) self.assertEqual(facts["series"]["leaf_count"], 10_000) self.assertEqual(facts["series"]["ranking"]["exponent"], 1.1) + self.assertEqual(facts["metrics"]["data"]["pareto_shape"], 2.0) self.assertEqual(facts["metrics"]["data_total"]["resets"], "none") self.assertEqual(facts["events"]["user_id_universe_size"], 10_000) self.assertEqual(facts["events"]["user_ids_per_leaf"], 1_000) From b6863ef95376ee955fc4fff97fc074ea2b61f61f Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:18:20 -0400 Subject: [PATCH 04/25] feat(asap-tools): render common baseline queries --- .../datasets/fake_metric/random_workloads.py | 40 +++++++++++++++++-- .../seed-862/workload-01.json | 16 ++++++-- .../seed-862/workload-02.json | 16 ++++++-- .../seed-862/workload-03.json | 16 ++++++-- .../seed-862/workload-04.json | 16 ++++++-- .../seed-862/workload-05.json | 16 ++++++-- .../seed-862/workload-06.json | 16 ++++++-- .../seed-862/workload-07.json | 16 ++++++-- .../seed-862/workload-08.json | 16 ++++++-- .../seed-862/workload-09.json | 16 ++++++-- .../seed-862/workload-10.json | 16 ++++++-- .../tests/test_random_workloads.py | 8 ++++ 12 files changed, 174 insertions(+), 34 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index b903f7da..fc64917f 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -61,6 +61,35 @@ def grouping_text(grouping): return ", ".join(grouping) +def clickhouse_time_filter(lookback_ms): + return f"ts BETWEEN NOW() - INTERVAL {lookback_ms // SECOND_MS} SECOND AND NOW()" + + +def clickhouse_sum(grouping, lookback_ms): + group = grouping_text(grouping) + return f"SELECT {group}, SUM(value) AS value FROM data WHERE {clickhouse_time_filter(lookback_ms)} GROUP BY {group}" + + +def clickhouse_quantile(grouping, phi): + group = grouping_text(grouping) + leaves = grouping_text(tuple(label["name"] for label in METRIC_LABELS)) + return ( + f"SELECT {group}, AVG(series_quantile) AS value FROM " + f"(SELECT {leaves}, quantileExact({phi:.2f})(value) AS series_quantile FROM data " + f"WHERE {clickhouse_time_filter(SPATIAL_LOOKBACK_MS)} GROUP BY {leaves}) GROUP BY {group}" + ) + + +def clickhouse_topk(grouping, lookback_ms, k, table="data", score="SUM(value)"): + group = grouping_text(grouping) + leaves = grouping_text(tuple(label["name"] for label in METRIC_LABELS)) + return ( + f"SELECT {leaves}, score FROM (SELECT *, row_number() OVER (PARTITION BY {group} " + f"ORDER BY score DESC) AS rank FROM (SELECT {leaves}, {score} AS score FROM {table} " + f"WHERE {clickhouse_time_filter(lookback_ms)} GROUP BY {leaves})) WHERE rank <= {k}" + ) + + def choose_temporal_time(rng): lookback_ms, intervals = rng.choice(TEMPORAL_TIMES) return lookback_ms, rng.choice(intervals) @@ -111,6 +140,7 @@ def query( interval_ms, rendered, support, + clickhouse_sql=None, **params, ): """Create one manifest query and its single optimizer-facing RQE.""" @@ -134,19 +164,18 @@ def query( "interval_ms": interval_ms, "promql": rendered if support != "sql-only" else None, "sql": rendered if support == "sql-only" else None, + "clickhouse_sql": clickhouse_sql or (rendered if support == "sql-only" else None), "rqes": [rqe], } def sum_query(query_id, grouping, lookback_ms, interval_ms): rendered = f"sum by ({grouping_text(grouping)}) (sum_over_time(data[{duration(lookback_ms)}]))" - return query( - query_id, "sum", grouping, lookback_ms, interval_ms, rendered, "common-promql" - ) + return query(query_id, "sum", grouping, lookback_ms, interval_ms, rendered, "common-promql", clickhouse_sql=clickhouse_sum(grouping, lookback_ms)) def quantile_query(query_id, grouping, phi): - rendered = f"quantile by ({grouping_text(grouping)}) ({phi:.2f}, data)" + rendered = f"avg by ({grouping_text(grouping)}) (quantile_over_time({phi:.2f}, data[1s]))" return query( query_id, "quantile", @@ -155,6 +184,7 @@ def quantile_query(query_id, grouping, phi): SPATIAL_INTERVAL_MS, rendered, "common-promql", + clickhouse_sql=clickhouse_quantile(grouping, phi), phi=phi, ) @@ -170,6 +200,7 @@ def topk_sum_query(query_id, grouping, lookback_ms, interval_ms, k): rendered, "common-promql", k=k, + clickhouse_sql=clickhouse_topk(grouping, lookback_ms, k), ) @@ -184,6 +215,7 @@ def topk_count_query(query_id, grouping, lookback_ms, interval_ms, k): rendered, "counter-gated-promql", k=k, + clickhouse_sql=clickhouse_topk(grouping, lookback_ms, k, "data_total"), ) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index 0b879d3a..929c6fb1 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,7 +127,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.99, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -145,6 +148,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -153,7 +157,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.95, data)", + "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -172,6 +176,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -182,7 +187,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.75, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -203,6 +208,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -232,6 +238,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -261,6 +268,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -290,6 +298,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -317,6 +326,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region, service", "grouping": [ "region", "service" diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index 2f009590..7385fa77 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -122,7 +125,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.75, data)", + "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -141,6 +144,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -150,7 +154,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.95, data)", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -170,6 +174,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -180,7 +185,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.99, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -201,6 +206,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -230,6 +236,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -259,6 +266,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -286,6 +294,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -313,6 +322,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index d12aa198..1cdacfe0 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -123,7 +126,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.95, data)", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -143,6 +146,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -152,7 +156,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.90, data)", + "promql": "avg by (region, service) (quantile_over_time(0.90, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -172,6 +176,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -182,7 +187,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.90, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.90, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -203,6 +208,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -230,6 +236,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -257,6 +264,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -286,6 +294,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -313,6 +322,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -60, NOW()) AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index 5cbf65ff..4a86fd4e 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -122,7 +125,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.75, data)", + "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -141,6 +144,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -150,7 +154,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.75, data)", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -170,6 +174,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -178,7 +183,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.95, data)", + "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -197,6 +202,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -226,6 +232,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -253,6 +260,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -282,6 +290,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -309,6 +318,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index f99ff415..d7bf452f 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -123,7 +126,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.99, data)", + "promql": "avg by (region, service) (quantile_over_time(0.99, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -143,6 +146,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -153,7 +157,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.50, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -174,6 +178,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -182,7 +187,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.90, data)", + "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -201,6 +206,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -230,6 +236,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -257,6 +264,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -286,6 +294,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -313,6 +322,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index 04787070..8bd20dde 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,7 +127,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.50, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -145,6 +148,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -154,7 +158,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.50, data)", + "promql": "avg by (region, service) (quantile_over_time(0.50, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -174,6 +178,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -182,7 +187,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.90, data)", + "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -201,6 +206,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region", "service" @@ -230,6 +236,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -259,6 +266,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -288,6 +296,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region", "service" @@ -317,6 +326,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index 5c0bcfc7..158bfd0a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,7 +127,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.99, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -145,6 +148,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -155,7 +159,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.95, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -176,6 +180,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -184,7 +189,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.50, data)", + "promql": "avg by (region) (quantile_over_time(0.50, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -203,6 +208,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -230,6 +236,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -259,6 +266,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -286,6 +294,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region", "service" @@ -315,6 +324,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region", "grouping": [ "region" ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index df564e7e..aa89ac42 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -123,7 +126,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.75, data)", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -143,6 +146,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -152,7 +156,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.95, data)", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -172,6 +176,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -180,7 +185,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.95, data)", + "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -199,6 +204,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -226,6 +232,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -253,6 +260,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region" ], @@ -280,6 +288,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region" ], @@ -307,6 +316,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region", "grouping": [ "region" ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index 8093c52a..0e82e37a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,7 +127,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.75, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -145,6 +148,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -155,7 +159,7 @@ "lookback_ms": 1000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "quantile by (region, service, job) (0.95, data)", + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -176,6 +180,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -185,7 +190,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.75, data)", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -205,6 +210,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -234,6 +240,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -263,6 +270,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", "grouping": [ "region" ], @@ -290,6 +298,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region", "service" @@ -319,6 +328,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, service, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -60, NOW()) AND NOW() GROUP BY region, service", "grouping": [ "region", "service" diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index 2bc74b80..b0d48e2a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -56,6 +56,7 @@ ], "queries": [ { + "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", "grouping": [ "region", "service", @@ -86,6 +87,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", "grouping": [ "region", "service" @@ -114,6 +116,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -123,7 +126,7 @@ "lookback_ms": 1000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "quantile by (region, service) (0.99, data)", + "promql": "avg by (region, service) (quantile_over_time(0.99, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -143,6 +146,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -151,7 +155,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.75, data)", + "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -170,6 +174,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -178,7 +183,7 @@ "lookback_ms": 1000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "quantile by (region) (0.90, data)", + "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -197,6 +202,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region" ], @@ -224,6 +230,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -253,6 +260,7 @@ "support": "common-promql" }, { + "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", "grouping": [ "region", "service" @@ -282,6 +290,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": null, "grouping": [ "region", "service" @@ -311,6 +320,7 @@ "support": "counter-gated-promql" }, { + "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region", "grouping": [ "region" ], diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index c064f1ef..d6735e5f 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -44,6 +44,14 @@ def test_manifest_declares_each_querys_rendering_and_output_cardinality(self): else: self.assertIsNone(query["sql"]) self.assertIn(" by (", query["promql"]) + if query["support"] == "common-promql": + self.assertIsNotNone(query["clickhouse_sql"]) + + def test_grouped_quantiles_use_average_of_per_series_quantiles(self): + for query in workloads.generate_workloads(seed=4)[0]["queries"]: + if query["rqes"][0]["capability"] == "quantile": + self.assertIn("avg by", query["promql"]) + self.assertIn("AVG(series_quantile)", query["clickhouse_sql"]) def test_visible_query_outputs_stay_bounded(self): for workload in workloads.generate_workloads(seed=4): From 0a6b378da9aa6df1a5865089790f1c9d5565cb4a Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:20:15 -0400 Subject: [PATCH 05/25] feat(asap-tools): render random workload pilot profiles --- .../fake_metric/random_workload_artifacts.py | 39 +++++++++++++++++++ .../tests/test_random_workload_artifacts.py | 9 +++++ 2 files changed, 48 insertions(+) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index e3aaab0b..8232e1d1 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -10,6 +10,8 @@ ACCURACY_SLA = 0.95 +PILOT_DURATION_MS = 10 * 60 * 1000 +QUERY_FRESHNESS_DELAY_SECS = 10 PROMQL_METRICS = ("data", "data_total") SQL_EVENTS_TABLE = { "name": "events", @@ -93,6 +95,39 @@ def query_groups(queries, query_key): ] +def pilot_profile(workload): + """Five-system workload-01 profile for the common PromQL query subset.""" + queries = [query for query in workload["queries"] if query["support"] == "common-promql"] + max_lookback_ms = max(query["lookback_ms"] for query in queries) + starting_delay = max_lookback_ms // 1000 + QUERY_FRESHNESS_DELAY_SECS + + def groups(query_key): + result = [] + for group in query_groups(queries, query_key): + interval = group["repetition_delay_ms"] + result.append( + { + **group, + "client_options": { + "starting_delay": starting_delay, + "repetitions": max(1, PILOT_DURATION_MS // interval), + "align_to_interval": True, + "query_time_offset": QUERY_FRESHNESS_DELAY_SECS, + }, + } + ) + return result + + return { + "workload_id": workload["id"], + "included_query_ids": [query["id"] for query in queries], + "excluded_query_ids": [query["id"] for query in workload["queries"] if query not in queries], + "data_ingestion_interval_ms": workload["data_facts"]["scrape_interval_ms"], + "promql_query_groups": groups("promql"), + "clickhouse_query_groups": groups("clickhouse_sql"), + } + + def render(workload): """Return planner inputs and query schedule derived from one manifest.""" labels = [label["name"] for label in workload["labels"]] @@ -102,6 +137,7 @@ def render(workload): "data_facts": workload["data_facts"], "queries": queries, "paced_feeder_table": paced_feeder_table(workload), + "pilot_profile": pilot_profile(workload), "promql_planner": { "metrics": [{"metric": metric, "labels": labels} for metric in PROMQL_METRICS], "query_groups": query_groups(queries, "promql"), @@ -144,6 +180,9 @@ def main(): table = args.out / "paced_feeder_table.json" table.write_text(json.dumps(rendered["paced_feeder_table"], indent=2, sort_keys=True) + "\n") print(table) + profile = args.out / "pilot_profile.yaml" + profile.write_text(yaml.safe_dump(rendered["pilot_profile"], sort_keys=False)) + print(profile) if __name__ == "__main__": diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 9471fb72..0ea827fe 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -51,6 +51,15 @@ def test_paced_feeder_table_preserves_all_manifest_data_facts(self): {"universe_keys": 10_000, "keys_per_series": 1_000}, ) + def test_pilot_profile_contains_only_common_queries(self): + profile = artifacts.pilot_profile(workloads.generate_workloads(seed=862)[0]) + + self.assertEqual(len(profile["included_query_ids"]), 7) + self.assertEqual(len(profile["excluded_query_ids"]), 3) + self.assertEqual(profile["data_ingestion_interval_ms"], 100) + self.assertTrue(profile["promql_query_groups"]) + self.assertTrue(profile["clickhouse_query_groups"]) + if __name__ == "__main__": unittest.main() From b367ffbb93f15382ba9e63d5521208e8c6c146a8 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:21:01 -0400 Subject: [PATCH 06/25] feat(asap-tools): support grouped pilot query shapes --- .../fake_metric/sketch_bench_workloads.py | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py index adeb011b..26b0b2de 100644 --- a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py @@ -109,7 +109,9 @@ LABELS = r"(\w+(?:, \w+)*)" LEVEL = r"([\d.]+)" TOPK = re.compile(r"^topk\((\d+), (.+)\)$") +TOPK_BY = re.compile(rf"^topk by \({LABELS}\) \((\d+), (.+)\)$") AGG_BY = re.compile(rf"^(sum|count) by \({LABELS}\) \((.+)\)$") +AVG_QUANTILE_BY = re.compile(rf"^avg by \({LABELS}\) \(quantile_over_time\(({LEVEL}), {RANGE}\)\)$") QUANTILE_BY = re.compile(rf"^quantile by \({LABELS}\) \({LEVEL}, (.+)\)$") OVER_TIME = re.compile(rf"^(sum|count)_over_time\({RANGE}\)$") QUANTILE_OVER_TIME = re.compile(rf"^quantile_over_time\({LEVEL}, {RANGE}\)$") @@ -142,6 +144,7 @@ class Query: quantile: Optional[str] = None # level as written, e.g. "0.99" ratio_quantile: Optional[str] = None topk: Optional[int] = None + topk_by: Optional[Tuple[str, ...]] = None value: str = VALUE_COLUMN left_open: bool = False @@ -206,6 +209,11 @@ def _grouped(inner: Query, agg: str, by: str, quantile: Optional[str]) -> Query: def parse_promql(promql: str, interval: int, labels: Dict[str, List[str]]) -> Query: """`labels`: each metric's label names in description order.""" text = " ".join(promql.split()) + m = TOPK_BY.match(text) + if m: + by, k, inner = m.groups() + query = _parse_series(inner, interval, labels, promql) + return replace(query, topk=int(k), topk_by=tuple(by.split(", "))) m = TOPK.match(text) if m: inner = parse_promql(m[2], interval, labels) @@ -216,6 +224,12 @@ def parse_promql(promql: str, interval: int, labels: Dict[str, List[str]]) -> Qu if m: agg, by, inner = m.groups() return _grouped(_parse_series(inner, interval, labels, promql), agg, by, None) + m = AVG_QUANTILE_BY.match(text) + if m: + by, quantile, _, name, amount, unit = m.groups() + if name not in labels: + raise ValueError(f"unknown metric {name!r} in {promql!r}") + return Query(name, interval, window_seconds(amount, unit), tuple(by.split(", ")), "per_series_quantile", "avg", quantile) m = QUANTILE_BY.match(text) if m: by, q, inner = m.groups() @@ -297,7 +311,10 @@ def render( # The grand total: one row, none for an empty window. sql = f"SELECT {value} AS value {window} HAVING count() > 0" else: - if q.series_fn == "last": + if q.series_fn == "per_series_quantile": + samples = f"SELECT {cols}, {agg('quantile', q.quantile)} AS value {window} GROUP BY {cols}" + sql = f"SELECT {group}, avg(value) AS value FROM ({samples}) GROUP BY {group}" + elif q.series_fn == "last": sql = ( f"SELECT {cols}, {agg('last', None)} AS value {window} GROUP BY {cols}" ) @@ -312,7 +329,10 @@ def render( combine = raw_agg(q.agg, q.quantile) sql = f"SELECT {group}, {combine} AS value FROM ({sql}) GROUP BY {group}" if q.topk is not None: - sql += f" ORDER BY value DESC, {group} LIMIT {q.topk}" + if q.topk_by: + sql = f"SELECT * FROM ({sql}) QUALIFY row_number() OVER (PARTITION BY {', '.join(q.topk_by)} ORDER BY value DESC) <= {q.topk}" + else: + sql += f" ORDER BY value DESC, {group} LIMIT {q.topk}" return sql From a3f4972865edb11918e2deb1ad7d7c15bcf8bdd4 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:21:29 -0400 Subject: [PATCH 07/25] feat(asap-tools): emit random workload E2E tables --- .../fake_metric/random_workload_artifacts.py | 19 +++++++++++++++++++ .../tests/test_random_workload_artifacts.py | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index 8232e1d1..e32c3b30 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -128,6 +128,21 @@ def groups(query_key): } +def pilot_e2e_table(workload): + """Render the common pilot as the existing sketch-bench E2E table shape.""" + table = paced_feeder_table(workload) + common = [query for query in workload["queries"] if query["support"] == "common-promql"] + table["workloads"][0]["e2e"]["queries"] = [ + { + "promql": query["promql"], + "interval_secs": query["interval_ms"] // 1000, + "rqes": [rqe["id"] for rqe in query["rqes"]], + } + for query in common + ] + return table + + def render(workload): """Return planner inputs and query schedule derived from one manifest.""" labels = [label["name"] for label in workload["labels"]] @@ -138,6 +153,7 @@ def render(workload): "queries": queries, "paced_feeder_table": paced_feeder_table(workload), "pilot_profile": pilot_profile(workload), + "pilot_e2e_table": pilot_e2e_table(workload), "promql_planner": { "metrics": [{"metric": metric, "labels": labels} for metric in PROMQL_METRICS], "query_groups": query_groups(queries, "promql"), @@ -183,6 +199,9 @@ def main(): profile = args.out / "pilot_profile.yaml" profile.write_text(yaml.safe_dump(rendered["pilot_profile"], sort_keys=False)) print(profile) + e2e_table = args.out / "pilot_e2e_table.json" + e2e_table.write_text(json.dumps(rendered["pilot_e2e_table"], indent=2, sort_keys=True) + "\n") + print(e2e_table) if __name__ == "__main__": diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 0ea827fe..f812573a 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -60,6 +60,14 @@ def test_pilot_profile_contains_only_common_queries(self): self.assertTrue(profile["promql_query_groups"]) self.assertTrue(profile["clickhouse_query_groups"]) + def test_pilot_e2e_table_is_consumable_by_existing_config_renderer(self): + table = artifacts.pilot_e2e_table(workloads.generate_workloads(seed=862)[0]) + e2e = table["workloads"][0]["e2e"] + + self.assertEqual(len(e2e["queries"]), 7) + self.assertEqual(set(e2e["metrics"]), {"data", "data_total", "events"}) + self.assertTrue(all(query["interval_secs"] >= 1 for query in e2e["queries"])) + if __name__ == "__main__": unittest.main() From d65802869778db57324ceaac9e2d67019818460a Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:21:50 -0400 Subject: [PATCH 08/25] fix(asap-tools): render grouped per-series quantiles --- .../experiments/datasets/fake_metric/sketch_bench_workloads.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py index 26b0b2de..98975fe4 100644 --- a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py @@ -325,7 +325,7 @@ def render( ) is_rate = q.series_fn == "rate" sql = rate_from_samples(cols, samples, end, q.window_secs, is_rate) - if q.agg is not None: + if q.agg is not None and q.series_fn != "per_series_quantile": combine = raw_agg(q.agg, q.quantile) sql = f"SELECT {group}, {combine} AS value FROM ({sql}) GROUP BY {group}" if q.topk is not None: From 883c6b81957d4cfc28964fe29bf4a118519f18ec Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:22:22 -0400 Subject: [PATCH 09/25] fix(asap-tools): plan MV views for per-series quantiles --- .../datasets/fake_metric/sketch_bench_workloads.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py index 98975fe4..651a4765 100644 --- a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py @@ -433,6 +433,8 @@ class View: def view_stat(q: Query) -> str: if q.series_fn is None: return q.agg + if q.series_fn == "per_series_quantile": + return "quantile" return "last" if q.series_fn == "last" else "counter" @@ -462,7 +464,11 @@ def plan_views(queries: List[Query], metrics: dict) -> Dict[tuple, View]: unknown = {p for p in parent.values() if p} - set(parent) if unknown: raise ValueError(f"{table!r}: child_of names unknown labels {unknown}") - keep = set(parent) if stat in PER_SERIES_STATS else set() + keep = ( + set(parent) + if stat in PER_SERIES_STATS or any(q.series_fn == "per_series_quantile" for q in qs) + else set() + ) for name in (n for q in qs for n in q.grouping): while name and name not in keep: keep.add(name) From ce7df9f3717f831973caf19c60af9a5005d885ba Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:23:13 -0400 Subject: [PATCH 10/25] revert(asap-tools): avoid PromQL-derived baseline SQL --- .../fake_metric/sketch_bench_workloads.py | 34 +++---------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py index 651a4765..adeb011b 100644 --- a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py @@ -109,9 +109,7 @@ LABELS = r"(\w+(?:, \w+)*)" LEVEL = r"([\d.]+)" TOPK = re.compile(r"^topk\((\d+), (.+)\)$") -TOPK_BY = re.compile(rf"^topk by \({LABELS}\) \((\d+), (.+)\)$") AGG_BY = re.compile(rf"^(sum|count) by \({LABELS}\) \((.+)\)$") -AVG_QUANTILE_BY = re.compile(rf"^avg by \({LABELS}\) \(quantile_over_time\(({LEVEL}), {RANGE}\)\)$") QUANTILE_BY = re.compile(rf"^quantile by \({LABELS}\) \({LEVEL}, (.+)\)$") OVER_TIME = re.compile(rf"^(sum|count)_over_time\({RANGE}\)$") QUANTILE_OVER_TIME = re.compile(rf"^quantile_over_time\({LEVEL}, {RANGE}\)$") @@ -144,7 +142,6 @@ class Query: quantile: Optional[str] = None # level as written, e.g. "0.99" ratio_quantile: Optional[str] = None topk: Optional[int] = None - topk_by: Optional[Tuple[str, ...]] = None value: str = VALUE_COLUMN left_open: bool = False @@ -209,11 +206,6 @@ def _grouped(inner: Query, agg: str, by: str, quantile: Optional[str]) -> Query: def parse_promql(promql: str, interval: int, labels: Dict[str, List[str]]) -> Query: """`labels`: each metric's label names in description order.""" text = " ".join(promql.split()) - m = TOPK_BY.match(text) - if m: - by, k, inner = m.groups() - query = _parse_series(inner, interval, labels, promql) - return replace(query, topk=int(k), topk_by=tuple(by.split(", "))) m = TOPK.match(text) if m: inner = parse_promql(m[2], interval, labels) @@ -224,12 +216,6 @@ def parse_promql(promql: str, interval: int, labels: Dict[str, List[str]]) -> Qu if m: agg, by, inner = m.groups() return _grouped(_parse_series(inner, interval, labels, promql), agg, by, None) - m = AVG_QUANTILE_BY.match(text) - if m: - by, quantile, _, name, amount, unit = m.groups() - if name not in labels: - raise ValueError(f"unknown metric {name!r} in {promql!r}") - return Query(name, interval, window_seconds(amount, unit), tuple(by.split(", ")), "per_series_quantile", "avg", quantile) m = QUANTILE_BY.match(text) if m: by, q, inner = m.groups() @@ -311,10 +297,7 @@ def render( # The grand total: one row, none for an empty window. sql = f"SELECT {value} AS value {window} HAVING count() > 0" else: - if q.series_fn == "per_series_quantile": - samples = f"SELECT {cols}, {agg('quantile', q.quantile)} AS value {window} GROUP BY {cols}" - sql = f"SELECT {group}, avg(value) AS value FROM ({samples}) GROUP BY {group}" - elif q.series_fn == "last": + if q.series_fn == "last": sql = ( f"SELECT {cols}, {agg('last', None)} AS value {window} GROUP BY {cols}" ) @@ -325,14 +308,11 @@ def render( ) is_rate = q.series_fn == "rate" sql = rate_from_samples(cols, samples, end, q.window_secs, is_rate) - if q.agg is not None and q.series_fn != "per_series_quantile": + if q.agg is not None: combine = raw_agg(q.agg, q.quantile) sql = f"SELECT {group}, {combine} AS value FROM ({sql}) GROUP BY {group}" if q.topk is not None: - if q.topk_by: - sql = f"SELECT * FROM ({sql}) QUALIFY row_number() OVER (PARTITION BY {', '.join(q.topk_by)} ORDER BY value DESC) <= {q.topk}" - else: - sql += f" ORDER BY value DESC, {group} LIMIT {q.topk}" + sql += f" ORDER BY value DESC, {group} LIMIT {q.topk}" return sql @@ -433,8 +413,6 @@ class View: def view_stat(q: Query) -> str: if q.series_fn is None: return q.agg - if q.series_fn == "per_series_quantile": - return "quantile" return "last" if q.series_fn == "last" else "counter" @@ -464,11 +442,7 @@ def plan_views(queries: List[Query], metrics: dict) -> Dict[tuple, View]: unknown = {p for p in parent.values() if p} - set(parent) if unknown: raise ValueError(f"{table!r}: child_of names unknown labels {unknown}") - keep = ( - set(parent) - if stat in PER_SERIES_STATS or any(q.series_fn == "per_series_quantile" for q in qs) - else set() - ) + keep = set(parent) if stat in PER_SERIES_STATS else set() for name in (n for q in qs for n in q.grouping): while name and name not in keep: keep.add(name) From f06bf404be6f39025d567cde232bd411dee043ff Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:33:51 -0400 Subject: [PATCH 11/25] feat(asap-tools): render random workload pilot planner input Co-Authored-By: Claude Opus 5.5 --- .../accelerated-random-workload-eval.md | 2 +- .../fake_metric/random_workload_artifacts.py | 46 +++++++++++++++---- .../tests/test_random_workload_artifacts.py | 30 ++++++++++-- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/.design_docs/accelerated-random-workload-eval.md b/.design_docs/accelerated-random-workload-eval.md index be3764f2..ed3bac16 100644 --- a/.design_docs/accelerated-random-workload-eval.md +++ b/.design_docs/accelerated-random-workload-eval.md @@ -5,7 +5,7 @@ Run a practical, end-to-end version of the paper's §6.2 experiment before the full PR 862 workload. The experiment should retain the important workload shape—many input series and few returned series—and show the benefit of -planning a *workload* of related RQEs rather than isolated queries. +planning a *workload* of related repeating query expressions (RQEs) rather than isolated queries. The experiment has ten deterministic random workloads. Each workload contains exactly ten atomic user queries; binary arithmetic queries are out of scope for diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index e32c3b30..d7e9f11d 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -64,8 +64,12 @@ def paced_feeder_table(workload): "values": { facts["events"]["distinct_key"]: { "rotating_pool": { - "universe_keys": facts["events"]["user_id_universe_size"], - "keys_per_series": facts["events"]["user_ids_per_leaf"], + "universe_keys": facts["events"][ + "user_id_universe_size" + ], + "keys_per_series": facts["events"][ + "user_ids_per_leaf" + ], } } }, @@ -91,13 +95,17 @@ def query_groups(queries, query_key): "queries": rendered, "controller_options": {"accuracy_sla": ACCURACY_SLA}, } - for index, (interval_ms, rendered) in enumerate(sorted(grouped.items()), start=1) + for index, (interval_ms, rendered) in enumerate( + sorted(grouped.items()), start=1 + ) ] def pilot_profile(workload): """Five-system workload-01 profile for the common PromQL query subset.""" - queries = [query for query in workload["queries"] if query["support"] == "common-promql"] + queries = [ + query for query in workload["queries"] if query["support"] == "common-promql" + ] max_lookback_ms = max(query["lookback_ms"] for query in queries) starting_delay = max_lookback_ms // 1000 + QUERY_FRESHNESS_DELAY_SECS @@ -121,7 +129,9 @@ def groups(query_key): return { "workload_id": workload["id"], "included_query_ids": [query["id"] for query in queries], - "excluded_query_ids": [query["id"] for query in workload["queries"] if query not in queries], + "excluded_query_ids": [ + query["id"] for query in workload["queries"] if query not in queries + ], "data_ingestion_interval_ms": workload["data_facts"]["scrape_interval_ms"], "promql_query_groups": groups("promql"), "clickhouse_query_groups": groups("clickhouse_sql"), @@ -131,7 +141,9 @@ def groups(query_key): def pilot_e2e_table(workload): """Render the common pilot as the existing sketch-bench E2E table shape.""" table = paced_feeder_table(workload) - common = [query for query in workload["queries"] if query["support"] == "common-promql"] + common = [ + query for query in workload["queries"] if query["support"] == "common-promql" + ] table["workloads"][0]["e2e"]["queries"] = [ { "promql": query["promql"], @@ -147,6 +159,7 @@ def render(workload): """Return planner inputs and query schedule derived from one manifest.""" labels = [label["name"] for label in workload["labels"]] queries = workload["queries"] + pilot_queries = [query for query in queries if query["support"] == "common-promql"] return { "workload_id": workload["id"], "data_facts": workload["data_facts"], @@ -155,10 +168,19 @@ def render(workload): "pilot_profile": pilot_profile(workload), "pilot_e2e_table": pilot_e2e_table(workload), "promql_planner": { - "metrics": [{"metric": metric, "labels": labels} for metric in PROMQL_METRICS], + "metrics": [ + {"metric": metric, "labels": labels} for metric in PROMQL_METRICS + ], "query_groups": query_groups(queries, "promql"), "aggregate_cleanup": {"policy": "read_based"}, }, + "pilot_promql_planner": { + "metrics": [ + {"metric": metric, "labels": labels} for metric in PROMQL_METRICS + ], + "query_groups": query_groups(pilot_queries, "promql"), + "aggregate_cleanup": {"policy": "read_based"}, + }, "sql_planner": { "tables": [SQL_EVENTS_TABLE], "query_groups": query_groups(queries, "sql"), @@ -175,7 +197,7 @@ def main(): workload = json.loads(args.manifest.read_text()) rendered = render(workload) args.out.mkdir(parents=True, exist_ok=True) - for name in ("promql_planner", "sql_planner"): + for name in ("promql_planner", "pilot_promql_planner", "sql_planner"): path = args.out / f"{name}.yaml" path.write_text(yaml.safe_dump(rendered[name], sort_keys=False)) print(path) @@ -194,13 +216,17 @@ def main(): ) print(schedule) table = args.out / "paced_feeder_table.json" - table.write_text(json.dumps(rendered["paced_feeder_table"], indent=2, sort_keys=True) + "\n") + table.write_text( + json.dumps(rendered["paced_feeder_table"], indent=2, sort_keys=True) + "\n" + ) print(table) profile = args.out / "pilot_profile.yaml" profile.write_text(yaml.safe_dump(rendered["pilot_profile"], sort_keys=False)) print(profile) e2e_table = args.out / "pilot_e2e_table.json" - e2e_table.write_text(json.dumps(rendered["pilot_e2e_table"], indent=2, sort_keys=True) + "\n") + e2e_table.write_text( + json.dumps(rendered["pilot_e2e_table"], indent=2, sort_keys=True) + "\n" + ) print(e2e_table) diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index f812573a..2b7f03d9 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -5,7 +5,9 @@ import unittest -sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "datasets", "fake_metric")) +sys.path.insert( + 0, os.path.join(os.path.dirname(__file__), "..", "datasets", "fake_metric") +) import random_workload_artifacts as artifacts # noqa: E402 import random_workloads as workloads # noqa: E402 @@ -19,7 +21,8 @@ def test_promql_input_groups_non_sql_queries_by_repeat_interval(self): planner = rendered["promql_planner"] expected = [q for q in rendered["queries"] if q["promql"]] self.assertEqual( - sum(len(group["queries"]) for group in planner["query_groups"]), len(expected) + sum(len(group["queries"]) for group in planner["query_groups"]), + len(expected), ) self.assertEqual( {tuple(metric["labels"]) for metric in planner["metrics"]}, @@ -27,15 +30,24 @@ def test_promql_input_groups_non_sql_queries_by_repeat_interval(self): ) self.assertEqual(rendered["data_facts"], workload["data_facts"]) for group in planner["query_groups"]: - self.assertTrue(all(query["interval_ms"] == group["repetition_delay_ms"] - for query in expected if query["promql"] in group["queries"])) + self.assertTrue( + all( + query["interval_ms"] == group["repetition_delay_ms"] + for query in expected + if query["promql"] in group["queries"] + ) + ) def test_sql_input_contains_only_sql_queries_and_their_table_schema(self): rendered = artifacts.render(workloads.generate_workloads(seed=862)[0]) self.assertTrue(rendered["sql_planner"]["query_groups"]) self.assertEqual(rendered["sql_planner"]["tables"][0]["name"], "events") - sql = [query for group in rendered["sql_planner"]["query_groups"] for query in group["queries"]] + sql = [ + query + for group in rendered["sql_planner"]["query_groups"] + for query in group["queries"] + ] self.assertTrue(all("COUNT(DISTINCT user_id)" in query for query in sql)) def test_paced_feeder_table_preserves_all_manifest_data_facts(self): @@ -60,6 +72,14 @@ def test_pilot_profile_contains_only_common_queries(self): self.assertTrue(profile["promql_query_groups"]) self.assertTrue(profile["clickhouse_query_groups"]) + def test_pilot_planner_excludes_gated_and_sql_only_queries(self): + rendered = artifacts.render(workloads.generate_workloads(seed=862)[0]) + groups = rendered["pilot_promql_planner"]["query_groups"] + + queries = [query for group in groups for query in group["queries"]] + self.assertEqual(len(queries), 7) + self.assertFalse(any("data_total" in query for query in queries)) + def test_pilot_e2e_table_is_consumable_by_existing_config_renderer(self): table = artifacts.pilot_e2e_table(workloads.generate_workloads(seed=862)[0]) e2e = table["workloads"][0]["e2e"] From d783d44163937683882e9867f1d90ca60bf480b5 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:36:34 -0400 Subject: [PATCH 12/25] feat(asap-tools): archive workload 01 pilot plan Co-Authored-By: Claude Opus 5.5 --- .../seed-862/workload-01-pilot/README.md | 13 ++ .../workload-01-pilot/inference_config.yaml | 82 +++++++++ .../pilot_promql_planner.yaml | 34 ++++ .../workload-01-pilot/streaming_config.yaml | 156 ++++++++++++++++++ .../tests/test_random_workload_artifacts.py | 17 ++ 5 files changed, 302 insertions(+) create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/streaming_config.yaml diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md new file mode 100644 index 00000000..2cd16b0b --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md @@ -0,0 +1,13 @@ +# Workload 01 pilot plan + +Planner input and legacy-planner output for workload 01's seven common-promql +queries at 100 ms ingestion. Regenerate from the repository root: + +```bash +python3 asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py \ + --manifest asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json \ + --out /tmp/w01 +cargo run --release --manifest-path asap-planner-rs/Cargo.toml --bin asap-planner -- \ + --input_config /tmp/w01/pilot_promql_planner.yaml --output_dir /tmp/w01/plan \ + --streaming_engine precompute --data-ingestion-interval-ms 100 +``` diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml new file mode 100644 index 00000000..812e6ea1 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml @@ -0,0 +1,82 @@ +cleanup_policy: + name: read_based +metrics: + data: + - job + - label_0 + - region + - service + data_total: + - job + - label_0 + - region + - service +queries: +- aggregations: + - aggregation_id: 1 + read_count_threshold: 1 + query: avg by (region, service, job) (quantile_over_time(0.99, data[1s])) + planned_subquery: quantile_over_time(0.99, data[1s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + read_count_threshold: 1 + query: avg by (region) (quantile_over_time(0.95, data[1s])) + planned_subquery: quantile_over_time(0.95, data[1s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + parameter: null +- aggregations: + - aggregation_id: 1 + read_count_threshold: 1 + query: avg by (region, service, job) (quantile_over_time(0.75, data[1s])) + planned_subquery: quantile_over_time(0.75, data[1s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 2 + read_count_threshold: 60 + query: topk by (region, service) (4, sum_over_time(data[1m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + read_count_threshold: 30 + - aggregation_id: 4 + read_count_threshold: 30 + query: sum by (region, service, job) (sum_over_time(data[10m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[10m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 5 + read_count_threshold: 30 + - aggregation_id: 6 + read_count_threshold: 30 + query: sum by (region, service) (sum_over_time(data[10m])) + planned_subquery: sum by (region, service) (sum_over_time(data[10m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 7 + read_count_threshold: 40 + query: topk by (region, service) (4, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[20m])) + query_time_aggregations: [] diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml new file mode 100644 index 00000000..b21ac4f2 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml @@ -0,0 +1,34 @@ +metrics: +- metric: data + labels: &id001 + - region + - service + - job + - label_0 +- metric: data_total + labels: *id001 +query_groups: +- id: 1 + repetition_delay_ms: 1000 + queries: + - avg by (region, service, job) (quantile_over_time(0.99, data[1s])) + - avg by (region) (quantile_over_time(0.95, data[1s])) + - avg by (region, service, job) (quantile_over_time(0.75, data[1s])) + - topk by (region, service) (4, sum_over_time(data[1m])) + controller_options: + accuracy_sla: 0.95 +- id: 2 + repetition_delay_ms: 20000 + queries: + - sum by (region, service, job) (sum_over_time(data[10m])) + - sum by (region, service) (sum_over_time(data[10m])) + controller_options: + accuracy_sla: 0.95 +- id: 3 + repetition_delay_ms: 30000 + queries: + - topk by (region, service) (4, sum_over_time(data[20m])) + controller_options: + accuracy_sla: 0.95 +aggregate_cleanup: + policy: read_based diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/streaming_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/streaming_config.yaml new file mode 100644 index 00000000..fc1e2a0e --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/streaming_config.yaml @@ -0,0 +1,156 @@ +aggregations: +- aggregationId: 1 + aggregationSubType: '' + aggregationType: DatasketchesKLL + labels: + aggregated: [] + grouping: + - job + - label_0 + - region + - service + rollup: [] + metric: data + parameters: + K: 500 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 1000 + windowType: tumbling +- aggregationId: 2 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + grouping: + - region + - service + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 16 + width: 1024 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 1000 + windowType: tumbling +- aggregationId: 3 + aggregationSubType: '' + aggregationType: DeltaSetAggregator + labels: + aggregated: + - job + - region + - service + grouping: [] + rollup: + - label_0 + metric: data + parameters: {} + slideIntervalMs: 20000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: tumbling +- aggregationId: 4 + aggregationSubType: sum + aggregationType: CountMinSketch + labels: + aggregated: + - job + - region + - service + grouping: [] + rollup: + - label_0 + metric: data + parameters: + depth: 3 + width: 1024 + slideIntervalMs: 20000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: tumbling +- aggregationId: 5 + aggregationSubType: '' + aggregationType: DeltaSetAggregator + labels: + aggregated: + - region + - service + grouping: [] + rollup: + - job + - label_0 + metric: data + parameters: {} + slideIntervalMs: 20000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: tumbling +- aggregationId: 6 + aggregationSubType: sum + aggregationType: CountMinSketch + labels: + aggregated: + - region + - service + grouping: [] + rollup: + - job + - label_0 + metric: data + parameters: + depth: 3 + width: 1024 + slideIntervalMs: 20000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: tumbling +- aggregationId: 7 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + grouping: + - region + - service + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 16 + width: 1024 + slideIntervalMs: 30000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 30000 + windowType: tumbling +metrics: + data: + - job + - label_0 + - region + - service + data_total: + - job + - label_0 + - region + - service diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 2b7f03d9..7e1761f0 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -4,6 +4,7 @@ import sys import unittest +import yaml sys.path.insert( 0, os.path.join(os.path.dirname(__file__), "..", "datasets", "fake_metric") @@ -80,6 +81,22 @@ def test_pilot_planner_excludes_gated_and_sql_only_queries(self): self.assertEqual(len(queries), 7) self.assertFalse(any("data_total" in query for query in queries)) + def test_archived_pilot_plan_input_matches_rendered_input(self): + # The archived planner output is only valid for the input it was run on. + rendered = artifacts.render(workloads.generate_workloads(seed=862)[0]) + archived = os.path.join( + os.path.dirname(__file__), + "..", + "datasets", + "fake_metric", + "random_workloads", + "seed-862", + "workload-01-pilot", + "pilot_promql_planner.yaml", + ) + with open(archived) as f: + self.assertEqual(yaml.safe_load(f), rendered["pilot_promql_planner"]) + def test_pilot_e2e_table_is_consumable_by_existing_config_renderer(self): table = artifacts.pilot_e2e_table(workloads.generate_workloads(seed=862)[0]) e2e = table["workloads"][0]["e2e"] From 1807e94e7df5f123a3956fcccd3045b200362aad Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 18:50:40 -0400 Subject: [PATCH 13/25] feat(asap-tools): give random quantiles a 100s lookback At 10 samples/s a 1s per-series quantile reads 10 samples, below the N = 1,000 where sketch-bench's accuracy curves start, so no saved plan can serve it. 100s reads exactly 1,000. Re-freezes seed 862 and the workload 01 pilot plan; other queries are unchanged. Co-Authored-By: Claude Opus 5.5 --- .../accelerated-random-workload-eval.md | 18 ++++----- .../datasets/fake_metric/random_workloads.py | 40 ++++++++++++++----- .../workload-01-pilot/inference_config.yaml | 18 ++++----- .../pilot_promql_planner.yaml | 6 +-- .../seed-862/workload-01.json | 24 +++++------ .../seed-862/workload-02.json | 24 +++++------ .../seed-862/workload-03.json | 24 +++++------ .../seed-862/workload-04.json | 24 +++++------ .../seed-862/workload-05.json | 24 +++++------ .../seed-862/workload-06.json | 24 +++++------ .../seed-862/workload-07.json | 24 +++++------ .../seed-862/workload-08.json | 24 +++++------ .../seed-862/workload-09.json | 24 +++++------ .../seed-862/workload-10.json | 24 +++++------ .../tests/test_random_workloads.py | 11 ++++- 15 files changed, 177 insertions(+), 156 deletions(-) diff --git a/.design_docs/accelerated-random-workload-eval.md b/.design_docs/accelerated-random-workload-eval.md index ed3bac16..4d3ac665 100644 --- a/.design_docs/accelerated-random-workload-eval.md +++ b/.design_docs/accelerated-random-workload-eval.md @@ -51,17 +51,19 @@ unbounded. | Lookback `W` | Allowed repeat intervals `T` | | ---: | ---: | -| 1 s | 1 s | +| 100 s | 1 s | | 1 min | 1 s, 2 s | | 5 min | 5 s, 10 s | | 10 min | 10 s, 20 s | | 20 min | 30 s, 60 s | The maximum accelerated backfill is therefore only 20 minutes of event-time -history. The first 1 s class is for spatial queries; temporal queries use the -1--20 minute classes. Scraping remains every 100 ms, so each spatial query -still consumes ten samples per leaf series. Its whole-second repetition and -lookback are compatible with the current exact-MV arm; it is not gated on +history. The first 100 s class is for quantile queries; the other temporal +queries use the 1--20 minute classes. Scraping remains every 100 ms, so each +quantile query consumes 1,000 samples per leaf series: the first N that +sketch-bench's accuracy curves cover, below which no saved plan can serve it. +Its whole-second repetition and lookback are compatible with the current +exact-MV arm; it is not gated on [#876](https://github.com/ProjectASAP/ASAPQuery/issues/876). That issue is needed only for a future sub-second query/MV schedule. @@ -118,12 +120,6 @@ first pilot workload. ### Quantile -For the 1 s spatial class, PromQL has exact grouped semantics: - -```promql -quantile by (G) (phi, data) -``` - For a temporal grouped quantile, PromQL cannot directly express a pooled quantile over every raw sample in each group. The PromQL-compatible rendering is instead the average of each leaf series' temporal quantile: diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index fc64917f..deb320eb 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -19,8 +19,10 @@ ACCURACY_SLA = 0.95 SECOND_MS = 1_000 MINUTE_MS = 60 * SECOND_MS -SPATIAL_LOOKBACK_MS = SECOND_MS -SPATIAL_INTERVAL_MS = SECOND_MS +# 100 s at 10 samples/s gives each series' quantile sketch 1,000 samples, the +# first N sketch-bench's accuracy curves cover. +QUANTILE_LOOKBACK_MS = 100 * SECOND_MS +QUANTILE_INTERVAL_MS = SECOND_MS LABEL_HIERARCHY = ( ("region", 4, None), ("service", 5, "region"), @@ -29,7 +31,11 @@ ) LABEL_CARDINALITIES = {name: cardinality for name, cardinality, _ in LABEL_HIERARCHY} METRIC_LABELS = [ - {"name": name, "cardinality": cardinality, **({"child_of": parent} if parent else {})} + { + "name": name, + "cardinality": cardinality, + **({"child_of": parent} if parent else {}), + } for name, cardinality, parent in LABEL_HIERARCHY ] GROUPINGS = (("region",), ("region", "service"), ("region", "service", "job")) @@ -76,7 +82,7 @@ def clickhouse_quantile(grouping, phi): return ( f"SELECT {group}, AVG(series_quantile) AS value FROM " f"(SELECT {leaves}, quantileExact({phi:.2f})(value) AS series_quantile FROM data " - f"WHERE {clickhouse_time_filter(SPATIAL_LOOKBACK_MS)} GROUP BY {leaves}) GROUP BY {group}" + f"WHERE {clickhouse_time_filter(QUANTILE_LOOKBACK_MS)} GROUP BY {leaves}) GROUP BY {group}" ) @@ -99,7 +105,7 @@ def workload_data_facts(seed): """Return the feeder contract shared by every workload from one seed.""" return { "feeder_seed": seed, - "scrape_interval_ms": SPATIAL_LOOKBACK_MS // 10, + "scrape_interval_ms": SECOND_MS // SAMPLES_PER_SEC_PER_SERIES, "backfill_history_ms": BACKFILL_HISTORY_MS, "series": { "leaf_count": LEAF_SERIES_COUNT, @@ -164,24 +170,34 @@ def query( "interval_ms": interval_ms, "promql": rendered if support != "sql-only" else None, "sql": rendered if support == "sql-only" else None, - "clickhouse_sql": clickhouse_sql or (rendered if support == "sql-only" else None), + "clickhouse_sql": clickhouse_sql + or (rendered if support == "sql-only" else None), "rqes": [rqe], } def sum_query(query_id, grouping, lookback_ms, interval_ms): rendered = f"sum by ({grouping_text(grouping)}) (sum_over_time(data[{duration(lookback_ms)}]))" - return query(query_id, "sum", grouping, lookback_ms, interval_ms, rendered, "common-promql", clickhouse_sql=clickhouse_sum(grouping, lookback_ms)) + return query( + query_id, + "sum", + grouping, + lookback_ms, + interval_ms, + rendered, + "common-promql", + clickhouse_sql=clickhouse_sum(grouping, lookback_ms), + ) def quantile_query(query_id, grouping, phi): - rendered = f"avg by ({grouping_text(grouping)}) (quantile_over_time({phi:.2f}, data[1s]))" + rendered = f"avg by ({grouping_text(grouping)}) (quantile_over_time({phi:.2f}, data[{QUANTILE_LOOKBACK_MS // SECOND_MS}s]))" return query( query_id, "quantile", grouping, - SPATIAL_LOOKBACK_MS, - SPATIAL_INTERVAL_MS, + QUANTILE_LOOKBACK_MS, + QUANTILE_INTERVAL_MS, rendered, "common-promql", clickhouse_sql=clickhouse_quantile(grouping, phi), @@ -326,7 +342,9 @@ def validate_workload(workload): if not 0 < events["user_ids_per_leaf"] <= events["user_id_universe_size"]: raise ValueError("distinct user pools must fit in the declared universe") if len(queries) != QUERIES_PER_WORKLOAD: - raise ValueError(f"a workload must contain exactly {QUERIES_PER_WORKLOAD} queries") + raise ValueError( + f"a workload must contain exactly {QUERIES_PER_WORKLOAD} queries" + ) if len({query["id"] for query in queries}) != len(queries): raise ValueError("query IDs must be unique") rqe_keys = { diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml index 812e6ea1..ad774d48 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml @@ -14,9 +14,9 @@ metrics: queries: - aggregations: - aggregation_id: 1 - read_count_threshold: 1 - query: avg by (region, service, job) (quantile_over_time(0.99, data[1s])) - planned_subquery: quantile_over_time(0.99, data[1s]) + read_count_threshold: 100 + query: avg by (region, service, job) (quantile_over_time(0.99, data[100s])) + planned_subquery: quantile_over_time(0.99, data[1m40s]) query_time_aggregations: - operator: avg grouping: @@ -28,9 +28,9 @@ queries: parameter: null - aggregations: - aggregation_id: 1 - read_count_threshold: 1 - query: avg by (region) (quantile_over_time(0.95, data[1s])) - planned_subquery: quantile_over_time(0.95, data[1s]) + read_count_threshold: 100 + query: avg by (region) (quantile_over_time(0.95, data[100s])) + planned_subquery: quantile_over_time(0.95, data[1m40s]) query_time_aggregations: - operator: avg grouping: @@ -40,9 +40,9 @@ queries: parameter: null - aggregations: - aggregation_id: 1 - read_count_threshold: 1 - query: avg by (region, service, job) (quantile_over_time(0.75, data[1s])) - planned_subquery: quantile_over_time(0.75, data[1s]) + read_count_threshold: 100 + query: avg by (region, service, job) (quantile_over_time(0.75, data[100s])) + planned_subquery: quantile_over_time(0.75, data[1m40s]) query_time_aggregations: - operator: avg grouping: diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml index b21ac4f2..785a51b1 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml @@ -11,9 +11,9 @@ query_groups: - id: 1 repetition_delay_ms: 1000 queries: - - avg by (region, service, job) (quantile_over_time(0.99, data[1s])) - - avg by (region) (quantile_over_time(0.95, data[1s])) - - avg by (region, service, job) (quantile_over_time(0.75, data[1s])) + - avg by (region, service, job) (quantile_over_time(0.99, data[100s])) + - avg by (region) (quantile_over_time(0.95, data[100s])) + - avg by (region, service, job) (quantile_over_time(0.75, data[100s])) - topk by (region, service) (4, sum_over_time(data[1m])) controller_options: accuracy_sla: 0.95 diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index 929c6fb1..e6530534 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,10 +124,10 @@ ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -139,7 +139,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.99 } @@ -148,16 +148,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -167,7 +167,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -176,7 +176,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -184,10 +184,10 @@ ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -199,7 +199,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index 7385fa77..efe41d1e 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -116,16 +116,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -135,7 +135,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -144,17 +144,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -165,7 +165,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -174,7 +174,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -182,10 +182,10 @@ ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -197,7 +197,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.99 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index 1cdacfe0..3c926df1 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -116,17 +116,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -137,7 +137,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -146,17 +146,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.90, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.90, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -167,7 +167,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.9 } @@ -176,7 +176,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -184,10 +184,10 @@ ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.90, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.90, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -199,7 +199,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index 4a86fd4e..2660a7cc 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -116,16 +116,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -135,7 +135,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -144,17 +144,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -165,7 +165,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -174,16 +174,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -193,7 +193,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index d7bf452f..93d016cc 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -116,17 +116,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.99, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.99, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -137,7 +137,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.99 } @@ -146,7 +146,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -154,10 +154,10 @@ ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -169,7 +169,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.5 } @@ -178,16 +178,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.90, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -197,7 +197,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index 8bd20dde..46d8a302 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,10 +124,10 @@ ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -139,7 +139,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.5 } @@ -148,17 +148,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.50, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.50, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -169,7 +169,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.5 } @@ -178,16 +178,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.90, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -197,7 +197,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index 158bfd0a..824e85cd 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,10 +124,10 @@ ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -139,7 +139,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.99 } @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -156,10 +156,10 @@ ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -171,7 +171,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -180,16 +180,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.50, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.50, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -199,7 +199,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.5 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index aa89ac42..a392cc3b 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -116,17 +116,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -137,7 +137,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -146,17 +146,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -167,7 +167,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -176,16 +176,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -195,7 +195,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index 0e82e37a..252ba9ed 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -124,10 +124,10 @@ ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -139,7 +139,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -156,10 +156,10 @@ ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 200, "output_series_upper_bound": 200, - "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[1s]))", + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -171,7 +171,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.95 } @@ -180,17 +180,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -201,7 +201,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index b0d48e2a..92ecbfc7 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -116,17 +116,17 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" ], "id": "q03-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 20, "output_series_upper_bound": 20, - "promql": "avg by (region, service) (quantile_over_time(0.99, data[1s]))", + "promql": "avg by (region, service) (quantile_over_time(0.99, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -137,7 +137,7 @@ ], "id": "q03-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.99 } @@ -146,16 +146,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q04-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.75, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.75, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -165,7 +165,7 @@ ], "id": "q04-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.75 } @@ -174,16 +174,16 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 1 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], "id": "q05-quantile", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "output_groups": 4, "output_series_upper_bound": 4, - "promql": "avg by (region) (quantile_over_time(0.90, data[1s]))", + "promql": "avg by (region) (quantile_over_time(0.90, data[100s]))", "rqes": [ { "accuracy_sla": 0.95, @@ -193,7 +193,7 @@ ], "id": "q05-quantile/rqe", "interval_ms": 1000, - "lookback_ms": 1000, + "lookback_ms": 100000, "metric": "data", "phi": 0.9 } diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index d6735e5f..f7da7310 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -61,11 +61,18 @@ def test_visible_query_outputs_stay_bounded(self): self.assertEqual(query["output_series_upper_bound"], expected) self.assertLessEqual(query["output_series_upper_bound"], 200) - def test_spatial_quantiles_repeat_at_whole_second_cadence(self): + def test_quantiles_cover_a_thousand_samples_per_series(self): + # sketch-bench's accuracy curves start at N = 1,000; below it no + # saved plan can serve the quantile. for workload in workloads.generate_workloads(seed=4): for query in workload["queries"]: if query["rqes"][0]["capability"] == "quantile": - self.assertEqual(query["lookback_ms"], workloads.SECOND_MS) + samples = ( + query["lookback_ms"] + // workload["data_facts"]["scrape_interval_ms"] + ) + self.assertEqual(samples, 1_000) + self.assertIn("data[100s]", query["promql"]) self.assertEqual(query["interval_ms"], workloads.SECOND_MS) def test_manifest_declares_deterministic_feeder_facts(self): From 304bde13cc2eed1ccf964afc473f812d60eb298b Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 19:03:01 -0400 Subject: [PATCH 14/25] test(asap-query-engine): cover avg of per-series quantile_over_time Co-Authored-By: Claude Opus 5.5 --- .../tests/e2e_precompute_equivalence.rs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/asap-query-engine/tests/e2e_precompute_equivalence.rs b/asap-query-engine/tests/e2e_precompute_equivalence.rs index 7ca83075..b0a1f3b0 100644 --- a/asap-query-engine/tests/e2e_precompute_equivalence.rs +++ b/asap-query-engine/tests/e2e_precompute_equivalence.rs @@ -2024,6 +2024,98 @@ async fn e2e_grouped_quantile_preserves_output_label_shape() { ); } +/// The average of per-series quantiles: per-series KLL windows merged over +/// the range, then averaged by group at query time. q=1 makes each series' +/// quantile its exact max, so a leaked or missing window changes the mean. +#[tokio::test] +async fn e2e_avg_of_per_series_quantile_over_time() { + use asap_types::query_config::{ + QueryTimeAggregationOperator, QueryTimeGrouping, QueryTimeGroupingMode, + }; + + let metric = "series_latency"; + let anchor = "quantile_over_time(1.0, series_latency[2s])"; + let query = "avg by (job) (quantile_over_time(1.0, series_latency[2s]))"; + let mut config = make_agg_config( + 19, + metric, + AggregationType::DatasketchesKLL, + "", + 1_000, + 0, + vec!["instance", "job"], + ); + config.parameters.insert("K".to_string(), json!(200_u64)); + // (instance, job, [(ts_ms, value)]): the 1_000 sample is outside (1s, 3s]. + let series = [ + ("a", "api", vec![(1_000, 100.0), (1_500, 1.0), (2_500, 9.0)]), + ("b", "api", vec![(1_500, 6.0), (2_500, 2.0)]), + ("c", "worker", vec![(1_500, 30.0), (2_500, 10.0)]), + ]; + let samples = series + .iter() + .flat_map(|(instance, job, points)| { + points + .iter() + .chain([(4_500, 0.0)].iter()) + .map(|&(ts, value)| { + make_timeseries( + metric, + vec![("instance", instance), ("job", job)], + ts, + value, + ) + }) + .collect::>() + }) + .collect(); + let (engine, query) = NativeDagScenario { + port: 19429, + metric, + query, + aggregation_configs: vec![config], + schema_labels: vec!["instance".to_string(), "job".to_string()], + samples, + evaluation_time_seconds: 3.0, + base_interval_ms: 1_000, + } + .build_engine_with_plan( + anchor, + vec![QueryTimeAggregation { + operator: QueryTimeAggregationOperator::Avg, + grouping: QueryTimeGrouping { + mode: QueryTimeGroupingMode::By, + labels: vec!["job".to_string()], + }, + parameter: None, + }], + ) + .await; + + let (output_labels, result) = engine + .handle_query_promql(query, 3.0) + .expect("avg of per-series quantiles should execute") + .expect("avg of per-series quantiles should match configured inference"); + assert_eq!(output_labels.labels, vec!["job"]); + let QueryResult::Vector(vector) = result else { + panic!("expected instant vector result"); + }; + let mut values: Vec<_> = vector + .values + .into_iter() + .map(|element| (element.labels.labels, element.value)) + .collect(); + values.sort_by(|a, b| a.0.cmp(&b.0)); + // api: mean of max(1, 9) and max(6, 2); worker: max(30, 10). + assert_eq!( + values, + vec![ + (vec!["api".to_string()], 7.5), + (vec!["worker".to_string()], 30.0) + ] + ); +} + /// A grouped quantile served by a DDSketch aggregation: samples from two /// instances per job flow through remote write and precompute into one /// DDSketch per group, and each returned quantile stays within the sketch's From af8888aa3ccda82561f2961856ea611d3e745ea7 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 19:08:24 -0400 Subject: [PATCH 15/25] feat(asap-planner): plan per-series avg as a query-time avg `avg by (G) (f(x[w]))` of a per-series function decomposes to the one leaf `f(x[w])` and is written as that leaf's aggregation plus a query-time avg, as the legacy planner writes it. Averaging per-series quantiles from sum and count leaves would be wrong. A binary arm can't run the stage, so such an arm is still refused. Co-Authored-By: Claude Opus 5.5 --- .../src/optimizer/aqe_extractor.rs | 47 ++++++++-- asap-planner-rs/src/optimizer/milp_output.rs | 91 ++++++++++++++++++- asap-planner-rs/src/optimizer/saved_plan.rs | 37 +++++++- 3 files changed, 166 insertions(+), 9 deletions(-) diff --git a/asap-planner-rs/src/optimizer/aqe_extractor.rs b/asap-planner-rs/src/optimizer/aqe_extractor.rs index f7f444ff..e755be57 100644 --- a/asap-planner-rs/src/optimizer/aqe_extractor.rs +++ b/asap-planner-rs/src/optimizer/aqe_extractor.rs @@ -10,7 +10,7 @@ use promql_utilities::query_logics::enums::Statistic; use crate::config::input::TableDefinition; use crate::planner::patterns::build_patterns; -use crate::planner::promql::{parse_binary_arms, BinaryArm}; +use crate::planner::promql::{parse_binary_arms, strip_parens, BinaryArm}; use crate::planner::sql::{parse_sql_query, sql_data_range_ms, sql_statistics}; use super::error::OptimizerError; @@ -261,21 +261,39 @@ pub(crate) fn decompose_to_leaves(query: &str) -> Vec { leaves } -/// Whether any leaf of `query` is an `avg` that `decompose_to_leaves` rewrites. +/// Whether `query` has an `avg` the engine can't answer: one that +/// `decompose_to_leaves` splits into sum and count, or a per-series avg in a +/// binary arm, which runs without its query-time avg. pub(crate) fn contains_avg(query: &str) -> bool { match parse_binary_arms(query) { - Some((lhs, rhs)) => [lhs, rhs] - .into_iter() - .any(|arm| matches!(arm, BinaryArm::Query(q) if contains_avg(&q))), + Some((lhs, rhs)) => [lhs, rhs].into_iter().any(|arm| { + matches!(arm, BinaryArm::Query(q) if contains_avg(&q) || per_series_avg(&q).is_some()) + }), None => rewrite_avg(query).len() > 1, } } +/// `avg by (l) (f(x[w]))` of a per-series function `f`: the leaf +/// `f(x[w])`, and the avg that averages its series at query time. +pub(crate) fn per_series_avg(query: &str) -> Option<(String, AggregateExpr)> { + match promql_parser::parser::parse(query).ok()? { + Expr::Aggregate(agg) if agg.op.id() == token::T_AVG => match strip_parens(&agg.expr) { + call @ Expr::Call(_) => Some((call.to_string(), agg)), + _ => None, + }, + _ => None, + } +} + /// Rewrite an `avg` leaf into the sum and count leaves it is computed from: /// `avg by (l) (x)` → `sum by (l) (x)`, `count by (l) (x)`, and /// `avg_over_time(x[5m])` → `sum_over_time(x[5m])`, `count_over_time(x[5m])`. -/// Any other query is returned unchanged. +/// A per-series avg is its leaf (see `per_series_avg`). Any other query is +/// returned unchanged. fn rewrite_avg(query: &str) -> Vec { + if let Some((leaf, _)) = per_series_avg(query) { + return vec![leaf]; + } match promql_parser::parser::parse(query) { Ok(Expr::Aggregate(agg)) if agg.op.id() == token::T_AVG => [token::T_SUM, token::T_COUNT] .into_iter() @@ -608,6 +626,23 @@ mod tests { assert!(items.iter().all(|i| i.requirements.statistics.len() == 1)); } + /// An avg of per-series quantiles averages the quantiles at query time; + /// sum and count items would ask for sums of quantiles. + #[test] + fn per_series_avg_is_its_per_series_leaf() { + let query = "avg by (job) (quantile_over_time(0.99, metric[5m]))"; + assert_eq!( + decompose_to_leaves(query), + vec!["quantile_over_time(0.99, metric[5m])"] + ); + let items = extract_aqes(&[rqe(query, 60_000)], &empty_schema(), 15_000).unwrap(); + let [item] = items.as_slice() else { + panic!("{items:?}"); + }; + assert_eq!(item.requirements.statistics, vec![Statistic::Quantile]); + assert!(item.requirements.grouping_labels.labels.is_empty()); + } + #[test] fn spatial_only_query_sets_range_to_scrape_interval() { let rqes = vec![rqe("sum(metric)", 60_000)]; diff --git a/asap-planner-rs/src/optimizer/milp_output.rs b/asap-planner-rs/src/optimizer/milp_output.rs index 5e33ce98..49de8c19 100644 --- a/asap-planner-rs/src/optimizer/milp_output.rs +++ b/asap-planner-rs/src/optimizer/milp_output.rs @@ -24,13 +24,16 @@ use crate::planner_output::PlannerOutput; use crate::promql::generator::{build_inference_yaml, build_streaming_yaml}; use crate::sql::generator::{build_sql_inference_yaml, build_sql_streaming_yaml}; -use super::aqe_extractor::{contains_avg, decompose_to_leaves}; +use super::aqe_extractor::{contains_avg, decompose_to_leaves, per_series_avg}; use super::milp::{MilpConfig, MilpWorkload}; use super::solution::OptimizerItem; #[derive(Debug, Error)] pub enum MilpOutputError { - #[error("query {0:?} uses avg, which the engine can't answer from sum and count yet")] + #[error( + "query {0:?} uses an avg the engine can't answer yet: from sum and count, or in a \ + binary arm" + )] AvgQuery(String), #[error( "query groups set step_ms or range_duration_ms, whose extra retention MILP \ @@ -227,6 +230,7 @@ pub fn deployments_to_planner_output( } } } + plan_per_series_avgs(config, &binary_leaves, &mut queries)?; let id_map: HashMap = aggregations .keys() @@ -342,6 +346,50 @@ fn query_plan_entry( }) } +/// Plans each per-series avg query (`per_series_avg`) as its leaf's entry +/// plus a query-time avg, replacing the leaf's entry unless the leaf is +/// itself a query or a binary query's arm. +fn plan_per_series_avgs( + config: MilpConfig, + binary_leaves: &HashSet, + queries: &mut IndexMap, +) -> Result<(), MilpOutputError> { + let MilpConfig::Promql(config) = config else { + return Ok(()); + }; + let asked: Vec<&String> = config + .query_groups + .iter() + .flat_map(|group| &group.queries) + .collect(); + let mut leaves = Vec::new(); + for &query in &asked { + let Some((leaf, avg)) = per_series_avg(query) else { + continue; + }; + let unregroupable = || MilpOutputError::UnregroupableQuery(query.clone()); + let entry = queries.get(&leaf).ok_or_else(unregroupable)?; + // The leaf keeps every label, so its aggregation is never regrouped. + if !entry.query_time_aggregations.is_empty() { + return Err(unregroupable()); + } + let stage = aggregation_stage(&avg).ok_or_else(unregroupable)?; + let planned = QueryPlanEntry { + aggregation_keys: entry.aggregation_keys.clone(), + planned_subquery: leaf.clone(), + query_time_aggregations: vec![stage], + }; + queries.insert(query.clone(), planned); + leaves.push(leaf); + } + for leaf in leaves { + if !asked.contains(&&leaf) && !binary_leaves.contains(&leaf) { + queries.shift_remove(&leaf); + } + } + Ok(()) +} + /// The leaves of the workload's binary queries. The engine runs a binary /// query's arms without query-time stages. fn binary_query_leaves(config: MilpConfig) -> HashSet { @@ -1091,6 +1139,45 @@ mod tests { assert!(matches!(err, MilpOutputError::AvgQuery(q) if q == query)); } + /// An avg of a per-series function reads that function's aggregation + /// and averages its series at query time; the bare leaf isn't a query. + #[test] + fn per_series_avg_averages_its_leaf_at_query_time() { + let query = "avg by (job) (quantile_over_time(0.99, http_requests_total[5m]))"; + let leaf = "quantile_over_time(0.99, http_requests_total[5m])"; + let (config, workload, solution) = plan(&group(query, 0.99)); + let output = + plan_to_planner_output(MilpConfig::Promql(&config), &workload, &solution).unwrap(); + + let a = aggregation_for(&output, query); + assert_eq!(a.aggregation_type, AggregationType::DatasketchesKLL); + let query_config = query_config_for(&output, query); + assert_eq!(query_config.planned_subquery, leaf); + let [stage] = query_config.query_time_aggregations.as_slice() else { + panic!("{:?}", query_config.query_time_aggregations); + }; + assert_eq!( + serde_json::to_value(stage).unwrap(), + json!({"operator": "avg", "grouping": {"mode": "by", "labels": ["job"]}, + "parameter": null}) + ); + stage.validate().unwrap(); + let inference = output.to_inference_config(QueryLanguage::promql).unwrap(); + assert!(inference.query_configs.iter().all(|q| q.query != leaf)); + } + + /// A binary query's arms run without query-time stages, so a per-series + /// avg arm can't be answered. + #[test] + fn per_series_avg_in_a_binary_arm_is_an_error() { + let query = "avg by (job) (quantile_over_time(0.99, http_requests_total[5m])) * 2"; + let (config, workload, solution) = plan(&group(query, 0.99)); + let err = plan_to_planner_output(MilpConfig::Promql(&config), &workload, &solution) + .err() + .unwrap(); + assert!(matches!(err, MilpOutputError::AvgQuery(q) if q == query)); + } + /// Range overrides only size retention, so they block writing configs /// but not planning. #[test] diff --git a/asap-planner-rs/src/optimizer/saved_plan.rs b/asap-planner-rs/src/optimizer/saved_plan.rs index 325274ad..13588e62 100644 --- a/asap-planner-rs/src/optimizer/saved_plan.rs +++ b/asap-planner-rs/src/optimizer/saved_plan.rs @@ -108,7 +108,7 @@ struct Chosen { /// Index of the plan's deployment. deployment: usize, /// Present only when the deployment's grouping differs from the RQE's - /// (a roll-up), which the converter refuses. + /// (a roll-up). deployment_grouping: Option, } @@ -583,6 +583,41 @@ mod tests { ); } + /// An avg of per-series quantiles is one leaf, the per-series quantile + /// its one RQE names, averaged by `job` at query time. + #[test] + fn writes_a_per_series_avg_as_a_query_time_avg() { + let query = "avg by (job) (quantile_over_time(0.5, data[5m]))"; + let table = TABLE.replace( + r#""quantile_over_time(0.5, data[5m])", "interval_secs": 60"#, + &format!(r#""{query}", "interval_secs": 60"#), + ); + let inference = run_on(&table, plans(shared_p50()).to_string().as_bytes(), None) + .unwrap() + .to_inference_config(asap_types::enums::QueryLanguage::promql) + .unwrap(); + let query_config = inference + .query_configs + .iter() + .find(|q| q.query == query) + .expect("a query_config for the avg"); + assert_eq!( + query_config.planned_subquery, + "quantile_over_time(0.5, data[5m])" + ); + let [stage] = query_config.query_time_aggregations.as_slice() else { + panic!("{:?}", query_config.query_time_aggregations); + }; + assert_eq!( + serde_json::to_value(stage).unwrap(), + json!({ + "operator": "avg", + "grouping": {"mode": "by", "labels": ["job"]}, + "parameter": null, + }) + ); + } + #[test] fn sla_ms_selects_the_plan_at_that_sla() { let yaml = run(plans(shared_p50()), Some(100.0)) From 3aed463067ab1ce343fcc53bb2af4f28cc81b443 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 19:14:24 -0400 Subject: [PATCH 16/25] feat(asap-tools): archive the saved workload 01 pilot plan Replaces the legacy-planner pilot plan with sketch-bench's saved plan (eval table from --random-manifest at sketch-bench 85699c9, autosketch_vs_asap p95) converted by --planner saved: the coarse sum rolls up from the fine sum, the quantiles share one per-series DDSketch with a query-time avg. Co-Authored-By: Claude Opus 5.5 --- .../seed-862/workload-01-pilot/README.md | 34 +- .../workload-01-pilot/eval_table.json | 448 ++++++++++++++++++ .../workload-01-pilot/inference_config.yaml | 72 ++- .../pilot_promql_planner.yaml | 34 -- .../seed-862/workload-01-pilot/plans.json.gz | Bin 0 -> 2288 bytes .../workload-01-pilot/streaming_config.yaml | 99 +--- .../tests/test_random_workload_artifacts.py | 21 +- 7 files changed, 541 insertions(+), 167 deletions(-) create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/eval_table.json delete mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/plans.json.gz diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md index 2cd16b0b..d1732bdb 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md @@ -1,13 +1,35 @@ # Workload 01 pilot plan -Planner input and legacy-planner output for workload 01's seven common-promql -queries at 100 ms ingestion. Regenerate from the repository root: +The saved sketch-bench plan for workload 01's seven common-promql queries at +100 ms ingestion, and its ASAPQuery configs: + +- `eval_table.json`: sketch-bench's eval table of the manifest + (`export_autosketch_eval_table.py --random-manifest`). +- `plans.json.gz`: each method's chosen plans (`autosketch_vs_asap`, p95). +- `streaming_config.yaml`, `inference_config.yaml`: the cheapest `asap` plan + on CPU weights, through `asap-planner --planner saved`. + +The `asap` plan serves the coarse sum from the fine sum's deployment (a +roll-up) and the three quantiles from one per-series DDSketch. Top-k heaps +over 500 series read the curves at their first 1,000 keys (the table's +`assumptions`). + +Regenerate, with `SB` a sketch-bench checkout at the table's +`sketch_bench_revision`, from this repository's root: ```bash -python3 asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py \ - --manifest asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json \ - --out /tmp/w01 +DIR=asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862 +OUT=$DIR/workload-01-pilot; SAT=$(mktemp -d); TMP=$(mktemp -d) +cp -r $SB/rqe-optimizer/results/autosketch-vs-asap-inputs/saturation/out_* $SAT/ +cp -r $SB/rqe-optimizer/results/autosketch-vs-asap-hydra/inputs/saturation/* $SAT/ +(cd $SB && cargo build --release -p rqe-optimizer --examples) +python3 $SB/scripts/export_autosketch_eval_table.py \ + --random-manifest $DIR/workload-01.json --out $OUT/eval_table.json +$SB/target/release/examples/autosketch_vs_asap synthetic --table $OUT/eval_table.json \ + --target p95 --runs 1 --saturation-dir $SAT --out $TMP/tp95.json +python3 $SB/scripts/extract_autosketch_plans.py $TMP/tp95.json $OUT/plans.json.gz cargo run --release --manifest-path asap-planner-rs/Cargo.toml --bin asap-planner -- \ - --input_config /tmp/w01/pilot_promql_planner.yaml --output_dir /tmp/w01/plan \ + --planner saved --workload-table $OUT/eval_table.json --plan $OUT/plans.json.gz \ + --method asap --weights cpu --output_dir $OUT \ --streaming_engine precompute --data-ingestion-interval-ms 100 ``` diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/eval_table.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/eval_table.json new file mode 100644 index 00000000..38e91a55 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/eval_table.json @@ -0,0 +1,448 @@ +{ + "inputs": { + "workload-01.json": "edacdc8662d75c0cd1c8bcc3136614225fd9f273d98360e73d8c563016586ae4" + }, + "plan": "ProjectASAP/ASAPQuery#879", + "schema_version": 1, + "sketch_bench_revision": "85699c9edef79ed6362ff19020d4c1f486af531d", + "workloads": [ + { + "dataset": "random/seed=862/workload-01", + "e2e": { + "metrics": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ], + "samples_per_sec_per_series": 10, + "type": "gauge", + "values": { + "dist": { + "pareto": 2.0 + }, + "value": { + "keys": 10000, + "zipf": 1.1 + } + } + } + }, + "queries": [ + { + "interval_secs": 20, + "promql": "sum by (region, service, job) (sum_over_time(data[10m]))", + "rqes": [ + "random/seed=862/workload-01/q01-sum-fine/keys/600s" + ] + }, + { + "interval_secs": 20, + "promql": "sum by (region, service) (sum_over_time(data[10m]))", + "rqes": [ + "random/seed=862/workload-01/q02-sum-coarse/keys/600s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", + "rqes": [ + "random/seed=862/workload-01/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region) (quantile_over_time(0.95, data[100s]))", + "rqes": [ + "random/seed=862/workload-01/q04-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[100s]))", + "rqes": [ + "random/seed=862/workload-01/q05-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "topk by (region, service) (4, sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-01/topk4_q06-topk-sum/keys/60s" + ] + }, + { + "interval_secs": 30, + "promql": "topk by (region, service) (4, sum_over_time(data[20m]))", + "rqes": [ + "random/seed=862/workload-01/topk4_q07-topk-sum/keys/1200s" + ] + } + ] + }, + "rqes": [ + { + "assumptions": [], + "capability": "sum", + "covered_groups": 200, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service", + "job" + ], + "id": "random/seed=862/workload-01/q01-sum-fine/keys/600s", + "instant": false, + "interval_secs": 20, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 200, + "keys_per_window": null + }, + "lookback_secs": 600.0, + "max_N": 300000.0, + "max_covered_share": 0.005, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.005, + "queries_per_instance": 1, + "query_id": "q01-sum-fine", + "range": "600s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "sum", + "covered_groups": 20, + "covered_max_N": 3000000.0, + "covered_min_N": 3000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-01/q02-sum-coarse/keys/600s", + "instant": false, + "interval_secs": 20, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": null + }, + "lookback_secs": 600.0, + "max_N": 3000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 3000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "q02-sum-coarse", + "range": "600s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-01/q03-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q03-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-01/q04-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q04-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-01/q05-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q05-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-01/topk4_q06-topk-sum/keys/60s", + "instant": false, + "interval_secs": 1, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 60.0, + "max_N": 300000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk4_q06-topk-sum", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 6000000.0, + "covered_min_N": 6000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-01", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-01/topk4_q07-topk-sum/keys/1200s", + "instant": false, + "interval_secs": 30, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 1200.0, + "max_N": 6000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 6000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk4_q07-topk-sum", + "range": "1200s", + "stream": "data/value" + } + ], + "schemas": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ] + } + } + } + ] +} diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml index ad774d48..9a005085 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/inference_config.yaml @@ -1,20 +1,46 @@ cleanup_policy: - name: read_based + name: circular_buffer metrics: data: - job - label_0 - region - service - data_total: - - job - - label_0 - - region - - service queries: +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service) (sum_over_time(data[10m])) + planned_subquery: sum by (job, region, service) (sum_over_time(data[10m])) + query_time_aggregations: + - operator: sum + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service, job) (sum_over_time(data[10m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[10m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + num_aggregates_to_retain: 59 + query: topk by (region, service) (4, sum_over_time(data[1m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 4 + num_aggregates_to_retain: 40 + query: topk by (region, service) (4, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[20m])) + query_time_aggregations: [] - aggregations: - aggregation_id: 1 - read_count_threshold: 100 + num_aggregates_to_retain: 76 query: avg by (region, service, job) (quantile_over_time(0.99, data[100s])) planned_subquery: quantile_over_time(0.99, data[1m40s]) query_time_aggregations: @@ -28,7 +54,7 @@ queries: parameter: null - aggregations: - aggregation_id: 1 - read_count_threshold: 100 + num_aggregates_to_retain: 76 query: avg by (region) (quantile_over_time(0.95, data[100s])) planned_subquery: quantile_over_time(0.95, data[1m40s]) query_time_aggregations: @@ -40,7 +66,7 @@ queries: parameter: null - aggregations: - aggregation_id: 1 - read_count_threshold: 100 + num_aggregates_to_retain: 76 query: avg by (region, service, job) (quantile_over_time(0.75, data[100s])) planned_subquery: quantile_over_time(0.75, data[1m40s]) query_time_aggregations: @@ -52,31 +78,3 @@ queries: - service - job parameter: null -- aggregations: - - aggregation_id: 2 - read_count_threshold: 60 - query: topk by (region, service) (4, sum_over_time(data[1m])) - planned_subquery: topk by (region, service) (4, sum_over_time(data[1m])) - query_time_aggregations: [] -- aggregations: - - aggregation_id: 3 - read_count_threshold: 30 - - aggregation_id: 4 - read_count_threshold: 30 - query: sum by (region, service, job) (sum_over_time(data[10m])) - planned_subquery: sum by (region, service, job) (sum_over_time(data[10m])) - query_time_aggregations: [] -- aggregations: - - aggregation_id: 5 - read_count_threshold: 30 - - aggregation_id: 6 - read_count_threshold: 30 - query: sum by (region, service) (sum_over_time(data[10m])) - planned_subquery: sum by (region, service) (sum_over_time(data[10m])) - query_time_aggregations: [] -- aggregations: - - aggregation_id: 7 - read_count_threshold: 40 - query: topk by (region, service) (4, sum_over_time(data[20m])) - planned_subquery: topk by (region, service) (4, sum_over_time(data[20m])) - query_time_aggregations: [] diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml deleted file mode 100644 index 785a51b1..00000000 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/pilot_promql_planner.yaml +++ /dev/null @@ -1,34 +0,0 @@ -metrics: -- metric: data - labels: &id001 - - region - - service - - job - - label_0 -- metric: data_total - labels: *id001 -query_groups: -- id: 1 - repetition_delay_ms: 1000 - queries: - - avg by (region, service, job) (quantile_over_time(0.99, data[100s])) - - avg by (region) (quantile_over_time(0.95, data[100s])) - - avg by (region, service, job) (quantile_over_time(0.75, data[100s])) - - topk by (region, service) (4, sum_over_time(data[1m])) - controller_options: - accuracy_sla: 0.95 -- id: 2 - repetition_delay_ms: 20000 - queries: - - sum by (region, service, job) (sum_over_time(data[10m])) - - sum by (region, service) (sum_over_time(data[10m])) - controller_options: - accuracy_sla: 0.95 -- id: 3 - repetition_delay_ms: 30000 - queries: - - topk by (region, service) (4, sum_over_time(data[20m])) - controller_options: - accuracy_sla: 0.95 -aggregate_cleanup: - policy: read_based diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/plans.json.gz b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/plans.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..dcd2f8832c63a7339bfe8355e73217752d34d8c7 GIT binary patch literal 2288 zcmZwGdpy$%AHeZd5*?H&9O_x=XE~F5>?oJx8r8}rO2%GphaoJFTw*Gh+Hl6ET$UUo zWoB{-+k=Uf(~y|9v4TQc_hiuLHM=!-Bm+ z!nFg#LqkCC^E^VwY?W=rJIAO)lKO%l39Pb3%HYh&r&BI9mU5@BrM+lLF5(1=ulk>+ zyccC;@3yQo#;X}KnQv<<&hjT^VlSbTCTu)?6BcL778~1_=*P6Grhd=9>)I)6c2OaZ zuhlJI8P^?{l|>hwI*hGEotx(uDc70Mu){N5ie)JG_|^HTth4dr`GN)anI~`zX~+#r z)d)4aTiwZw7D|>?k^3l@;?2?E zg^}_PDRb5Qp;fk@!Lz8SsIj+&lzU{CH%Hp*uLwp1Jh?w~Dtev4EWTWr6lhLP;^^nl zun3qF`o1Ep=5X8gT2rHa`CLLtOV?3LYZ$Jm`&j1a;@(eCukeg_P^WASF4P`;|F-Cq z??Up`ZSb}fGLGDLyx2-F#UX|7-PfR1DzmHygTXzT25BRxFU^;GO7S*tb}jQ)+x)l` zWS@E?k3X!xActS7L)KSLyA;x7f=(+%3n%%Z!(FFVQZXJv&!3yHbC2d?K0rKwdsmD; zVv}jNm)t__?VZrRi7juQ-^H+m(Tv(!X`T}^wG(dO#f9tPQ=gpJXKJ$l*~xN_j2R7~ zI-~kwjnrvI$8zDLrsb|I?ISK-ovdyBrO0@<$*|0odI#i4m&n~L_?6KAQ?g%0_E&JS zpm){jE_YTIzE7zq2IUcLxTq@THFj3u#(M2EoeBi+jA!<7BZNwBZu{%IkJ%@=!0<&2 zq++*GM6=3CZd%!Gkq|!YV7X$oeaOvB)vpa6CkUi=PNSF0{r2UDE0FC>c0&Gx7rhtIHfk-V+95IHa*90wB9qexRCGJhpPD}rEw|xoh8*;a zp)l&(0aAebXSUj*+qxC}FvhF%*YVhegi1*7s zH__H?&C)82_3-Nrtxo04zSWAwkjuO2Q-R+ucBK(@4cIhR8pk>d2C=?{=8xd`D2k3>~^N+_I-5g)L z@@jnV(8mmTWL1MR-3YZQ^s+FrN31ayG_Bbbu%BFe#q;5BOKE+2aefi01a}sbO;LzR zVa;ekbNOTQ6CBOPsC&1qP|Xp)?qO8@{^>!5Lxy5Tn)BTg59KE_zUBT!g~{uPjs+Q& z>E2V0pd^Z%ch1W9wp>kAJ@}70`H)1_QD)?fX-JZ-7<;rS-Dsgd+b)OgZN5L~! z!7;EP!rLmGGt%RO+iHJPemnSYME*eruF;Q?It`|JFGYP_56r=5eJqIqr0)`PfkB-c zxv^k?jgyx)XAnLf`X=>fe4Mf4J=j}MaQ|bJmA6EQrT#1kR6gHar^4jw(vvZUsij`X zj^mK?RjsKzO^GxWQ(_c(-6Alz=ru^%X$l^_Fga5(n18`{95iu+bLw@Ue6a;$}gDz%bxdDF(pR zt($THV<5r1;Y8py4v@C6Oy3PitYsW4fm7c|+Cn&xU`^T#d7sHre>G3rw-iW^+`m%h zVbd)>1e`0f@fGZGCN>=^28`kV<i5X-ZpJn(G2G z(pHT0S=_N8-36)XPp8oSb-YEj-e}jRzc|*V)6W85*R` z+|9`Q{D~h`{E3a^b*}2spDmur>_CHs*0~aD*X<5~Z>{Ar>Q+ncMu}?qukqI8&3Gn% zNM0g-QMp8HA+PgP$9=Xq5mks_0t7f(;kzChAToQe9NJ?4Tmb{dC#n_LX{?34@)J0GlhoLg2H=Q|M8i~4{ Date: Wed, 14 Oct 2026 20:08:45 -0400 Subject: [PATCH 17/25] refactor(asap-tools): drop the unused pilot planner input The pilot is planned by sketch-bench and --planner saved, which reads its queries from the eval table. Co-Authored-By: Claude Opus 5.5 --- .../datasets/fake_metric/random_workload_artifacts.py | 10 +--------- .../tests/test_random_workload_artifacts.py | 8 -------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index d7e9f11d..132682dc 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -159,7 +159,6 @@ def render(workload): """Return planner inputs and query schedule derived from one manifest.""" labels = [label["name"] for label in workload["labels"]] queries = workload["queries"] - pilot_queries = [query for query in queries if query["support"] == "common-promql"] return { "workload_id": workload["id"], "data_facts": workload["data_facts"], @@ -174,13 +173,6 @@ def render(workload): "query_groups": query_groups(queries, "promql"), "aggregate_cleanup": {"policy": "read_based"}, }, - "pilot_promql_planner": { - "metrics": [ - {"metric": metric, "labels": labels} for metric in PROMQL_METRICS - ], - "query_groups": query_groups(pilot_queries, "promql"), - "aggregate_cleanup": {"policy": "read_based"}, - }, "sql_planner": { "tables": [SQL_EVENTS_TABLE], "query_groups": query_groups(queries, "sql"), @@ -197,7 +189,7 @@ def main(): workload = json.loads(args.manifest.read_text()) rendered = render(workload) args.out.mkdir(parents=True, exist_ok=True) - for name in ("promql_planner", "pilot_promql_planner", "sql_planner"): + for name in ("promql_planner", "sql_planner"): path = args.out / f"{name}.yaml" path.write_text(yaml.safe_dump(rendered[name], sort_keys=False)) print(path) diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 64970639..e514dca6 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -72,14 +72,6 @@ def test_pilot_profile_contains_only_common_queries(self): self.assertTrue(profile["promql_query_groups"]) self.assertTrue(profile["clickhouse_query_groups"]) - def test_pilot_planner_excludes_gated_and_sql_only_queries(self): - rendered = artifacts.render(workloads.generate_workloads(seed=862)[0]) - groups = rendered["pilot_promql_planner"]["query_groups"] - - queries = [query for group in groups for query in group["queries"]] - self.assertEqual(len(queries), 7) - self.assertFalse(any("data_total" in query for query in queries)) - def test_archived_pilot_plan_reads_the_manifest_s_pilot_queries(self): # The archived plan is only valid for the queries it was solved for. workload = workloads.generate_workloads(seed=862)[0] From 6eaf0ae0aebd6d3280d72412ea8020fb111f7036 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 20:18:33 -0400 Subject: [PATCH 18/25] feat(asap-tools): render per-group top-k and avg of per-series quantiles The ClickHouse renderers take a Query; these shapes are built from RQEs, not parsed from PromQL. A per-series quantile reads a view keyed by every label, and top-k by keeps k rows per group (LIMIT k BY). Raw SQL matches the Prometheus reference and MV SQL matches raw in clickhouse-local. Co-Authored-By: Claude Opus 5.5 --- .../fake_metric/sketch_bench_workloads.py | 32 +++++++---- .../tests/test_sketch_bench_workloads.py | 54 +++++++++++++++++-- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py index adeb011b..01fd972f 100644 --- a/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/sketch_bench_workloads.py @@ -126,11 +126,13 @@ class Query: With `series_fn` None, `agg` runs over the raw samples of each `grouping` group in the window (sum_over_time, sum by (job) (sum_over_time), ...). - Otherwise `series_fn` (last, rate, increase) gives one value per series, - and `agg` combines those per group; `agg` None keeps them per series. + Otherwise `series_fn` (last, rate, increase, or quantile at `quantile`) + gives one value per series, and `agg` combines those per group (avg by + (job) (quantile_over_time)); `agg` None keeps them per series. `ratio_quantile` divides the `quantile` by a second quantile of the same - samples. Structured (non-PromQL) query entries map onto these fields and - set `left_open`: their window is (end - W, end], not PromQL's closed one. + samples. `topk` keeps the k largest values, per `topk_by` group when set. + Structured (non-PromQL) query entries map onto these fields and set + `left_open`: their window is (end - W, end], not PromQL's closed one. """ table: str @@ -142,6 +144,7 @@ class Query: quantile: Optional[str] = None # level as written, e.g. "0.99" ratio_quantile: Optional[str] = None topk: Optional[int] = None + topk_by: Tuple[str, ...] = () value: str = VALUE_COLUMN left_open: bool = False @@ -297,10 +300,9 @@ def render( # The grand total: one row, none for an empty window. sql = f"SELECT {value} AS value {window} HAVING count() > 0" else: - if q.series_fn == "last": - sql = ( - f"SELECT {cols}, {agg('last', None)} AS value {window} GROUP BY {cols}" - ) + if q.series_fn in ("last", "quantile"): + value = agg(q.series_fn, q.quantile) + sql = f"SELECT {cols}, {value} AS value {window} GROUP BY {cols}" else: samples = ( f"SELECT {cols}, {agg('counter', None)} {window} " @@ -313,6 +315,8 @@ def render( sql = f"SELECT {group}, {combine} AS value FROM ({sql}) GROUP BY {group}" if q.topk is not None: sql += f" ORDER BY value DESC, {group} LIMIT {q.topk}" + if q.topk_by: + sql += f" BY {', '.join(q.topk_by)}" return sql @@ -321,6 +325,8 @@ def raw_agg(stat: str, quantile: Optional[str], value: str = VALUE_COLUMN) -> st return f"sum({value})" if stat == "count": return "count()" + if stat == "avg": + return f"avg({value})" if stat == "cardinality": return f"uniqExact({value})" if stat == "quantile": @@ -413,7 +419,9 @@ class View: def view_stat(q: Query) -> str: if q.series_fn is None: return q.agg - return "last" if q.series_fn == "last" else "counter" + if q.series_fn in ("last", "quantile"): + return q.series_fn + return "counter" def mv_servable(q: Query) -> bool: @@ -425,7 +433,8 @@ def plan_views(queries: List[Query], metrics: dict) -> Dict[tuple, View]: """One view per (table, value, statistic, interval), keyed by view_key(). Pooled statistics keep the union of their queries' groupings plus every label's child_of parents, so coarser groupings roll up; - per-series statistics keep every label.""" + per-series statistics, and any view a per-series query reads, keep every + label.""" grouped: Dict[tuple, List[Query]] = {} for q in queries: if not mv_servable(q): @@ -442,7 +451,8 @@ def plan_views(queries: List[Query], metrics: dict) -> Dict[tuple, View]: unknown = {p for p in parent.values() if p} - set(parent) if unknown: raise ValueError(f"{table!r}: child_of names unknown labels {unknown}") - keep = set(parent) if stat in PER_SERIES_STATS else set() + per_series = stat in PER_SERIES_STATS or any(q.series_fn for q in qs) + keep = set(parent) if per_series else set() for name in (n for q in qs for n in q.grouping): while name and name not in keep: keep.add(name) diff --git a/asap-tools/experiments/tests/test_sketch_bench_workloads.py b/asap-tools/experiments/tests/test_sketch_bench_workloads.py index 8b3540b3..1330a381 100644 --- a/asap-tools/experiments/tests/test_sketch_bench_workloads.py +++ b/asap-tools/experiments/tests/test_sketch_bench_workloads.py @@ -653,6 +653,49 @@ def q_ratio(t, gauge): lambda t, g, c: q_ratio(t, g), ), ] + + +def topk_by(k: int, vec: Vector, idx: List[int]) -> Vector: + out: Vector = {} + for group in {tuple(s[i] for i in idx) for s in vec}: + members = {s: v for s, v in vec.items() if tuple(s[i] for i in idx) == group} + out.update(topk(k, members)) + return out + + +ALL_LABELS = ("job", "label_0") +# Shapes the random workloads build from their RQEs, not from PromQL: +# (name, Query, reference over (gauge, counter) at eval time t ms). +RQE_CASES = [ + ( + "avg by (job) (quantile_over_time(0.9, data[2m]))", + sbw.Query("data", 60, 120, ("job",), "quantile", "avg", "0.9"), + lambda t, g, c: agg_by( + range_fn(g, t, W2, lambda w: prom_quantile(0.9, values(w))), + JOB, + lambda vs: sum(vs) / len(vs), + ), + ), + ( + "topk by (job) (2, sum_over_time(data[2m]))", + sbw.Query("data", 60, 120, ALL_LABELS, None, "sum", topk=2, topk_by=("job",)), + lambda t, g, c: topk_by(2, range_fn(g, t, W2, lambda w: sum(values(w))), JOB), + ), + ( + "topk by (job) (2, increase(data_total[5m]))", + sbw.Query( + "data_total", + 60, + 300, + ALL_LABELS, + "increase", + None, + topk=2, + topk_by=("job",), + ), + lambda t, g, c: topk_by(2, rate(c, t, W5, False), JOB), + ), +] EVAL_OFFSETS_SECS = { # Before data, data start (the only sample sits on the window's end), # mid-run, around series 2's gap and series 1's end, and after all data. @@ -814,6 +857,10 @@ def all_cases(gauge, counter, records) -> List[Tuple[str, "sbw.Query", Callable] (p, sbw.parse_promql(p, t, LABELS), lambda e, ref=ref: ref(e, gauge, counter)) for t, p, ref in CASES ] + cases += [ + (name, q, lambda e, ref=ref: ref(e, gauge, counter)) + for name, q, ref in RQE_CASES + ] for entry in MULTIGROUP: q = sbw.query_from_entry(entry, METRICS, LABELS) w_ms = q.window_secs * 1000 @@ -954,9 +1001,10 @@ def test_raw_sql_matches_prometheus_reference(self): def test_mv_sql_matches_raw_sql(self): for i, (name, q, _) in enumerate(self.cases): - # Only sums are re-associated (per bucket, then across buckets and - # groups); every other statistic merges to the identical value. - rel = 1e-9 if q.agg == "sum" else 0.0 + # Only sums and averages are re-associated (per bucket, then across + # buckets and groups); every other statistic merges to the + # identical value. + rel = 1e-9 if q.agg in ("sum", "avg") else 0.0 for offset in EVAL_OFFSETS_SECS[q.interval_secs]: with self.subTest(query=name, offset=offset): raw = self.got[f"raw/{i}@{offset}"] From 2bbef6f6738a14aedfd407244ed6e9c396551830 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 20:19:57 -0400 Subject: [PATCH 19/25] feat(asap-tools): render random workload ClickHouse SQL from RQEs Each RQE maps to the ClickHouse renderers' Query, so the manifest's clickhouse_sql is the same SQL the MV arm is checked against: windows floored to the eval time, Prometheus 2.53 boundaries, top-k per group. The cardinality RQE now names its table, events. Re-freezes seed 862; PromQL is unchanged. Co-Authored-By: Claude Opus 5.5 --- .../datasets/fake_metric/random_workloads.py | 98 ++++++++++++------- .../seed-862/workload-01.json | 22 ++--- .../seed-862/workload-02.json | 22 ++--- .../seed-862/workload-03.json | 22 ++--- .../seed-862/workload-04.json | 22 ++--- .../seed-862/workload-05.json | 22 ++--- .../seed-862/workload-06.json | 22 ++--- .../seed-862/workload-07.json | 22 ++--- .../seed-862/workload-08.json | 22 ++--- .../seed-862/workload-09.json | 22 ++--- .../seed-862/workload-10.json | 22 ++--- .../tests/test_random_workloads.py | 10 +- 12 files changed, 181 insertions(+), 147 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads.py b/asap-tools/experiments/datasets/fake_metric/random_workloads.py index deb320eb..9e39a690 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads.py @@ -12,6 +12,7 @@ import random from pathlib import Path +from sketch_bench_workloads import Query, raw_sql WORKLOAD_COUNT = 10 QUERIES_PER_WORKLOAD = 10 @@ -53,6 +54,11 @@ TOPK_VALUES = (4, 8) BACKFILL_HISTORY_MS = 20 * MINUTE_MS LEAF_SERIES_COUNT = math.prod(LABEL_CARDINALITIES.values()) +LEAF_LABELS = tuple(name for name, _, _ in LABEL_HIERARCHY) +# Every ClickHouse table has the leaf labels (sketch_bench_workloads' tables). +CLICKHOUSE_LABELS = { + table: list(LEAF_LABELS) for table in ("data", "data_total", "events") +} ZIPF_EXPONENT = 1.1 USER_ID_UNIVERSE_SIZE = 10_000 USER_IDS_PER_LEAF = 1_000 @@ -67,33 +73,56 @@ def grouping_text(grouping): return ", ".join(grouping) -def clickhouse_time_filter(lookback_ms): - return f"ts BETWEEN NOW() - INTERVAL {lookback_ms // SECOND_MS} SECOND AND NOW()" - - -def clickhouse_sum(grouping, lookback_ms): - group = grouping_text(grouping) - return f"SELECT {group}, SUM(value) AS value FROM data WHERE {clickhouse_time_filter(lookback_ms)} GROUP BY {group}" - - -def clickhouse_quantile(grouping, phi): - group = grouping_text(grouping) - leaves = grouping_text(tuple(label["name"] for label in METRIC_LABELS)) - return ( - f"SELECT {group}, AVG(series_quantile) AS value FROM " - f"(SELECT {leaves}, quantileExact({phi:.2f})(value) AS series_quantile FROM data " - f"WHERE {clickhouse_time_filter(QUANTILE_LOOKBACK_MS)} GROUP BY {leaves}) GROUP BY {group}" - ) - - -def clickhouse_topk(grouping, lookback_ms, k, table="data", score="SUM(value)"): - group = grouping_text(grouping) - leaves = grouping_text(tuple(label["name"] for label in METRIC_LABELS)) - return ( - f"SELECT {leaves}, score FROM (SELECT *, row_number() OVER (PARTITION BY {group} " - f"ORDER BY score DESC) AS rank FROM (SELECT {leaves}, {score} AS score FROM {table} " - f"WHERE {clickhouse_time_filter(lookback_ms)} GROUP BY {leaves})) WHERE rank <= {k}" - ) +def rqe_query(rqe): + """The ClickHouse renderers' Query for one RQE, built from its fields, + never from its PromQL. Raw and MV ClickHouse SQL both render it.""" + capability, grouping = rqe["capability"], tuple(rqe["grouping_labels"]) + common = { + "table": rqe["metric"], + "interval_secs": rqe["interval_ms"] // SECOND_MS, + "window_secs": rqe["lookback_ms"] // SECOND_MS, + } + if capability == "sum": + return Query(**common, grouping=grouping, series_fn=None, agg="sum") + if capability == "quantile": + quantile = f"{rqe['phi']:.2f}" + return Query( + **common, + grouping=grouping, + series_fn="quantile", + agg="avg", + quantile=quantile, + ) + if capability == "topk_by_value": + return Query( + **common, + grouping=LEAF_LABELS, + series_fn=None, + agg="sum", + topk=rqe["k"], + topk_by=grouping, + ) + if capability in ("topk_by_count", "rate"): + series_fn = "increase" if capability == "topk_by_count" else "rate" + return Query( + **common, + grouping=LEAF_LABELS, + series_fn=series_fn, + agg=None, + topk=rqe["k"], + topk_by=grouping, + ) + if capability == "cardinality": + # Planner SQL windows are left-open, (E - W, E]. + return Query( + **common, + grouping=grouping, + series_fn=None, + agg="cardinality", + value=rqe["value"], + left_open=True, + ) + raise ValueError(f"unknown capability {capability!r}") def choose_temporal_time(rng): @@ -146,14 +175,18 @@ def query( interval_ms, rendered, support, - clickhouse_sql=None, **params, ): """Create one manifest query and its single optimizer-facing RQE.""" + metrics = { + "rate": "data_total", + "topk_by_count": "data_total", + "cardinality": "events", + } rqe = { "id": f"{query_id}/rqe", "capability": capability, - "metric": "data_total" if capability in ("rate", "topk_by_count") else "data", + "metric": metrics.get(capability, "data"), "grouping_labels": list(grouping), "lookback_ms": lookback_ms, "interval_ms": interval_ms, @@ -170,8 +203,7 @@ def query( "interval_ms": interval_ms, "promql": rendered if support != "sql-only" else None, "sql": rendered if support == "sql-only" else None, - "clickhouse_sql": clickhouse_sql - or (rendered if support == "sql-only" else None), + "clickhouse_sql": raw_sql(rqe_query(rqe), CLICKHOUSE_LABELS), "rqes": [rqe], } @@ -186,7 +218,6 @@ def sum_query(query_id, grouping, lookback_ms, interval_ms): interval_ms, rendered, "common-promql", - clickhouse_sql=clickhouse_sum(grouping, lookback_ms), ) @@ -200,7 +231,6 @@ def quantile_query(query_id, grouping, phi): QUANTILE_INTERVAL_MS, rendered, "common-promql", - clickhouse_sql=clickhouse_quantile(grouping, phi), phi=phi, ) @@ -216,7 +246,6 @@ def topk_sum_query(query_id, grouping, lookback_ms, interval_ms, k): rendered, "common-promql", k=k, - clickhouse_sql=clickhouse_topk(grouping, lookback_ms, k), ) @@ -231,7 +260,6 @@ def topk_count_query(query_id, grouping, lookback_ms, interval_ms, k): rendered, "counter-gated-promql", k=k, - clickhouse_sql=clickhouse_topk(grouping, lookback_ms, k, "data_total"), ) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json index e6530534..90fe68c0 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.99)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -176,7 +176,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -208,7 +208,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -238,7 +238,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -268,7 +268,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 20) * 20 - 600) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 20) * 20 - 600)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 20) * 20 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 20) * 20 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -298,7 +298,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 30) * 30 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 30) * 30 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 30) * 30 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 30) * 30 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -326,7 +326,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -348,7 +348,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 20000, "lookback_ms": 600000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json index efe41d1e..8dfd95b9 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -144,7 +144,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -174,7 +174,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.99)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -206,7 +206,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -236,7 +236,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -266,7 +266,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 5) * 5 - 300) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 5) * 5 - 300)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 5) * 5 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 5) * 5 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -294,7 +294,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 60) * 60 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 60) * 60 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 60) * 60 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 60) * 60 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -322,7 +322,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -346,7 +346,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 5000, "lookback_ms": 300000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json index 3c926df1..d38c985a 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -146,7 +146,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.90)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -176,7 +176,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.90)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -208,7 +208,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -236,7 +236,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -264,7 +264,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 1) * 1 - 60) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 1) * 1 - 60)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 1) * 1 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 1) * 1 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -294,7 +294,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 30) * 30 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 30) * 30 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 30) * 30 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 30) * 30 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -322,7 +322,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -60, NOW()) AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -346,7 +346,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 1000, "lookback_ms": 60000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json index 2660a7cc..26356bfb 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -144,7 +144,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -174,7 +174,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -202,7 +202,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -232,7 +232,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -260,7 +260,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 10) * 10 - 600) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 10) * 10 - 600)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 10) * 10 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 10) * 10 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -290,7 +290,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 30) * 30 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 30) * 30 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 30) * 30 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 30) * 30 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region", "grouping": [ "region" ], @@ -318,7 +318,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 10) * 10 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -342,7 +342,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 10000, "lookback_ms": 600000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json index 93d016cc..c4776746 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.99)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -146,7 +146,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.50)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -178,7 +178,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.90)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -206,7 +206,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -236,7 +236,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -264,7 +264,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 10) * 10 - 300) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 10) * 10 - 300)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 10) * 10 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 10) * 10 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -294,7 +294,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 60) * 60 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 60) * 60 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 60) * 60 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 60) * 60 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region", "grouping": [ "region" ], @@ -322,7 +322,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -346,7 +346,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 10000, "lookback_ms": 300000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json index 46d8a302..987a1b73 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.50)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.50)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -178,7 +178,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.90)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -206,7 +206,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -236,7 +236,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -266,7 +266,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 5) * 5 - 300) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 5) * 5 - 300)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 5) * 5 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 5) * 5 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -296,7 +296,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 60) * 60 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 60) * 60 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 60) * 60 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 60) * 60 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -326,7 +326,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, job, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 5) * 5 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 5) * 5, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -350,7 +350,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 5000, "lookback_ms": 300000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json index 824e85cd..ef803fee 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.99)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -180,7 +180,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.50)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.50)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -208,7 +208,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -236,7 +236,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -266,7 +266,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 20) * 20 - 600) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 20) * 20 - 600)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 20) * 20 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 20) * 20 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -294,7 +294,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 60) * 60 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 60) * 60 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 60) * 60 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 60) * 60 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -324,7 +324,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region", + "clickhouse_sql": "SELECT region, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region", "grouping": [ "region" ], @@ -344,7 +344,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 20000, "lookback_ms": 600000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json index a392cc3b..aca22cb7 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -146,7 +146,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -176,7 +176,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -204,7 +204,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -232,7 +232,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -260,7 +260,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 300 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 10) * 10 - 300) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 10) * 10 - 300)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 10) * 10 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 10) * 10 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region", "grouping": [ "region" ], @@ -288,7 +288,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 30) * 30 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 30) * 30 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 30) * 30 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 30) * 30 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -316,7 +316,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -300, NOW()) AND NOW() GROUP BY region", + "clickhouse_sql": "SELECT region, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 10) * 10 - 300, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 10) * 10, 3) GROUP BY region", "grouping": [ "region" ], @@ -336,7 +336,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 10000, "lookback_ms": 300000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json index 252ba9ed..f984d0cd 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -148,7 +148,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.95)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.95)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -180,7 +180,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -210,7 +210,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -240,7 +240,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -270,7 +270,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 4", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 2) * 2 - 60) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 2) * 2 - 60)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 2) * 2 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 2) * 2 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region", "grouping": [ "region" ], @@ -298,7 +298,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 30) * 30 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 30) * 30 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 30) * 30 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 30) * 30 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 30) * 30 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 30) * 30, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -328,7 +328,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, service, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -60, NOW()) AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -350,7 +350,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 2000, "lookback_ms": 60000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json index 92ecbfc7..59f05c09 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10.json @@ -56,7 +56,7 @@ ], "queries": [ { - "clickhouse_sql": "SELECT region, service, job, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job", + "clickhouse_sql": "SELECT region, service, job, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job", "grouping": [ "region", "service", @@ -87,7 +87,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, SUM(value) AS value FROM data WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service", "grouping": [ "region", "service" @@ -116,7 +116,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.99)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region, service", + "clickhouse_sql": "SELECT region, service, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.99)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region, service", "grouping": [ "region", "service" @@ -146,7 +146,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.75)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.75)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -174,7 +174,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, AVG(series_quantile) AS value FROM (SELECT region, service, job, label_0, quantileExact(0.90)(value) AS series_quantile FROM data WHERE ts BETWEEN NOW() - INTERVAL 100 SECOND AND NOW() GROUP BY region, service, job, label_0) GROUP BY region", + "clickhouse_sql": "SELECT region, avg(value) AS value FROM (SELECT region, service, job, label_0, quantileExactInclusive(0.90)(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 1) * 1 - 100, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 1) * 1, 3) GROUP BY region, service, job, label_0) GROUP BY region", "grouping": [ "region" ], @@ -202,7 +202,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 60 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 2) * 2 - 60, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 2) * 2, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region", "grouping": [ "region" ], @@ -230,7 +230,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data WHERE ts BETWEEN NOW() - INTERVAL 1200 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, sum(value) AS value FROM data WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -260,7 +260,7 @@ "support": "common-promql" }, { - "clickhouse_sql": "SELECT region, service, job, label_0, score FROM (SELECT *, row_number() OVER (PARTITION BY region, service ORDER BY score DESC) AS rank FROM (SELECT region, service, job, label_0, SUM(value) AS score FROM data_total WHERE ts BETWEEN NOW() - INTERVAL 600 SECOND AND NOW() GROUP BY region, service, job, label_0)) WHERE rank <= 8", + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 20) * 20 - 600) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 20) * 20 - 600)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 20) * 20 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 20) * 20 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 8 BY region, service", "grouping": [ "region", "service" @@ -290,7 +290,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": null, + "clickhouse_sql": "SELECT region, service, job, label_0, delta * (sampled + to_start + to_end) / sampled / 1200 AS value FROM (SELECT region, service, job, label_0, last_v - first_v AS delta, first_v, last_t - first_t AS sampled, sampled / (n - 1) AS avg_step, if(first_t - (intDiv({{ end_time }}, 60) * 60 - 1200) >= 1.1 * avg_step, avg_step / 2, first_t - (intDiv({{ end_time }}, 60) * 60 - 1200)) AS to_start_clamped, if(delta > 0 AND first_v >= 0, least(to_start_clamped, sampled * first_v / delta), to_start_clamped) AS to_start, if(intDiv({{ end_time }}, 60) * 60 - last_t >= 1.1 * avg_step, avg_step / 2, intDiv({{ end_time }}, 60) * 60 - last_t) AS to_end FROM (SELECT region, service, job, label_0, argMin(value, ts) AS first_v, argMax(value, ts) AS last_v, toFloat64(min(ts)) AS first_t, toFloat64(max(ts)) AS last_t, count() AS n FROM data_total WHERE ts >= toDateTime64(intDiv({{ end_time }}, 60) * 60 - 1200, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 60) * 60, 3) GROUP BY region, service, job, label_0 HAVING n >= 2)) ORDER BY value DESC, region, service, job, label_0 LIMIT 4 BY region, service", "grouping": [ "region", "service" @@ -320,7 +320,7 @@ "support": "counter-gated-promql" }, { - "clickhouse_sql": "SELECT region, COUNT(DISTINCT user_id) FROM events WHERE ts BETWEEN DATEADD(s, -600, NOW()) AND NOW() GROUP BY region", + "clickhouse_sql": "SELECT region, uniqExact(user_id) AS value FROM events WHERE ts > toDateTime64(intDiv({{ end_time }}, 20) * 20 - 600, 3) AND ts <= toDateTime64(intDiv({{ end_time }}, 20) * 20, 3) GROUP BY region", "grouping": [ "region" ], @@ -340,7 +340,7 @@ "id": "q10-cardinality/rqe", "interval_ms": 20000, "lookback_ms": 600000, - "metric": "data", + "metric": "events", "value": "user_id" } ], diff --git a/asap-tools/experiments/tests/test_random_workloads.py b/asap-tools/experiments/tests/test_random_workloads.py index f7da7310..00a8bc97 100644 --- a/asap-tools/experiments/tests/test_random_workloads.py +++ b/asap-tools/experiments/tests/test_random_workloads.py @@ -48,10 +48,16 @@ def test_manifest_declares_each_querys_rendering_and_output_cardinality(self): self.assertIsNotNone(query["clickhouse_sql"]) def test_grouped_quantiles_use_average_of_per_series_quantiles(self): + # The SQL each Query renders is checked against Prometheus in + # test_sketch_bench_workloads. for query in workloads.generate_workloads(seed=4)[0]["queries"]: - if query["rqes"][0]["capability"] == "quantile": + rqe = query["rqes"][0] + if rqe["capability"] == "quantile": self.assertIn("avg by", query["promql"]) - self.assertIn("AVG(series_quantile)", query["clickhouse_sql"]) + q = workloads.rqe_query(rqe) + self.assertEqual((q.series_fn, q.agg), ("quantile", "avg")) + self.assertEqual(q.grouping, tuple(query["grouping"])) + self.assertEqual(q.window_secs, 100) def test_visible_query_outputs_stay_bounded(self): for workload in workloads.generate_workloads(seed=4): From 53bdcafb85fc4c5a0e84eed9cda7a45462c59d1f Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 20:22:52 -0400 Subject: [PATCH 20/25] feat(asap-tools): render the five-system pilot run configs --pilot-dir writes, under config/experiment_type/random_workload/: ASAPQuery (the archived saved plan) and Prometheus, VictoriaMetrics, raw ClickHouse (the manifest's clickhouse_sql) and ClickHouse+MV (the same RQEs over exact views). Every arm feeds the eval table's metrics with the manifest's feeder seed and evaluates on one schedule: the longest lookback plus the freshness delay, then 10 min aligned to each interval. Replaces pilot_profile and pilot_e2e_table. Co-Authored-By: Claude Opus 5.5 --- .../fake_metric/random_workload_artifacts.py | 192 ++++++++++++------ .../tests/test_random_workload_artifacts.py | 161 ++++++++++++--- 2 files changed, 268 insertions(+), 85 deletions(-) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index 132682dc..a18dbdd1 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -1,17 +1,36 @@ #!/usr/bin/env python3 -"""Render frozen random-workload manifests into offline planner inputs.""" +"""Render frozen random-workload manifests into offline planner inputs and, +with --pilot-dir, the five-system pilot's run configs.""" import argparse +import copy import json +import os +import sys from collections import defaultdict from pathlib import Path import yaml +import sketch_bench_workloads as sbw +from random_workloads import CLICKHOUSE_LABELS, rqe_query + +EXPERIMENTS_DIR = os.path.dirname( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +) +sys.path.insert(0, EXPERIMENTS_DIR) +from sketch_bench_e2e.sketch_bench_e2e_configs import ( # noqa: E402 + BASELINE_MODE, + build_config, +) ACCURACY_SLA = 0.95 +PILOT_SUPPORT = "common-promql" PILOT_DURATION_MS = 10 * 60 * 1000 QUERY_FRESHNESS_DELAY_SECS = 10 +# Relative to EXPERIMENTS_DIR, where the runners read configs and SQL. +CONFIG_DIR = "config/experiment_type/random_workload" +VICTORIAMETRICS_URL = "http://localhost:8428" PROMQL_METRICS = ("data", "data_total") SQL_EVENTS_TABLE = { "name": "events", @@ -101,58 +120,111 @@ def query_groups(queries, query_key): ] -def pilot_profile(workload): - """Five-system workload-01 profile for the common PromQL query subset.""" - queries = [ - query for query in workload["queries"] if query["support"] == "common-promql" - ] - max_lookback_ms = max(query["lookback_ms"] for query in queries) - starting_delay = max_lookback_ms // 1000 + QUERY_FRESHNESS_DELAY_SECS - - def groups(query_key): - result = [] - for group in query_groups(queries, query_key): - interval = group["repetition_delay_ms"] - result.append( - { - **group, - "client_options": { - "starting_delay": starting_delay, - "repetitions": max(1, PILOT_DURATION_MS // interval), - "align_to_interval": True, - "query_time_offset": QUERY_FRESHNESS_DELAY_SECS, - }, - } - ) - return result +def pilot_configs(workload, pilot_dir): + """The five-system pilot's run configs, {path under EXPERIMENTS_DIR: + content}: ASAPQuery (the saved plan in `pilot_dir`) and Prometheus in + one experiment_run_e2e.py config, VictoriaMetrics in another, and raw + and MV ClickHouse in one experiment_run_clickhouse.py config each. - return { - "workload_id": workload["id"], - "included_query_ids": [query["id"] for query in queries], - "excluded_query_ids": [ - query["id"] for query in workload["queries"] if query not in queries - ], - "data_ingestion_interval_ms": workload["data_facts"]["scrape_interval_ms"], - "promql_query_groups": groups("promql"), - "clickhouse_query_groups": groups("clickhouse_sql"), - } + Every arm feeds the metrics of `pilot_dir`'s eval table with the + manifest's feeder seed, waits out the longest lookback plus the + freshness delay, then evaluates each query at multiples of its interval + for PILOT_DURATION_MS: the same windows relative to its data start. + Raw ClickHouse runs the manifest's clickhouse_sql, and ClickHouse+MV + the same RQEs' Query over exact views (sketch_bench_workloads).""" + queries = [q for q in workload["queries"] if q["support"] == PILOT_SUPPORT] + lookback_secs = max(q["lookback_ms"] for q in queries) // 1000 + starting_delay = lookback_secs + QUERY_FRESHNESS_DELAY_SECS + duration = PILOT_DURATION_MS // 1000 + seed = workload["data_facts"]["feeder_seed"] + table = pilot_dir / "eval_table.json" + out_dir = Path(CONFIG_DIR) / workload["id"] + e2e, _ = build_config( + str(table), + seed, + starting_delay, + duration, + QUERY_FRESHNESS_DELAY_SECS, + prebuilt_output_dir=str(pilot_dir), + ) + # One monitoring tool per run, so VictoriaMetrics is its own baseline run. + vm = copy.deepcopy(e2e) + del vm["controller"] + vm_params = vm["experiment_params"] + vm_params["experiment"] = [BASELINE_MODE] + vm_params["monitoring"] = { + "tool": "victoriametrics", + "deployment_mode": "containerized", + } + for server in vm_params["servers"]: + if server["name"] == "prometheus": + server["url"] = VICTORIAMETRICS_URL -def pilot_e2e_table(workload): - """Render the common pilot as the existing sketch-bench E2E table shape.""" - table = paced_feeder_table(workload) - common = [ - query for query in workload["queries"] if query["support"] == "common-promql" - ] - table["workloads"][0]["e2e"]["queries"] = [ - { - "promql": query["promql"], - "interval_secs": query["interval_ms"] // 1000, - "rqes": [rqe["id"] for rqe in query["rqes"]], + metrics = json.loads(table.read_text())["workloads"][0]["e2e"]["metrics"] + rqe_queries = [rqe_query(query["rqes"][0]) for query in queries] + views = sbw.plan_views(rqe_queries, metrics) + files = { + "init.sql": sbw.init_sql(metrics, [], create_views=False), + "init_mv.sql": sbw.init_sql(metrics, list(views.values()), create_views=True), + } + statements = defaultdict(lambda: {sbw.BASELINE: [], sbw.BASELINE_MV: []}) + for query, q in zip(queries, rqe_queries): + sql = { + sbw.BASELINE: query["clickhouse_sql"], + sbw.BASELINE_MV: sbw.mv_sql(q, views, CLICKHOUSE_LABELS), } - for query in common - ] - return table + for mode, text in sql.items(): + statements[q.interval_secs][mode].append(f"-- {query['promql']}\n{text}") + groups = [] + for interval, by_mode in sorted(statements.items()): + sql_files = {} + for mode, texts in by_mode.items(): + name = f"interval_{interval}s_{mode}.sql" + files[name] = sbw.statements_text(texts) + sql_files[mode] = str(out_dir / name) + groups.append( + { + "name": f"interval_{interval}s", + "sql_file": sql_files, + "repetition_delay_ms": interval * 1000, + # The SQL reads only {{ end_time }}; the client requires a value. + "time_window_seconds": 0, + "client_options": { + "starting_delay": starting_delay, + "repetitions": duration // interval, + "align_to_interval": True, + "query_time_offset": QUERY_FRESHNESS_DELAY_SECS, + }, + } + ) + feeder = { + "workload_table": str(table.resolve()), + "metrics": list(metrics), + "seed": seed, + "duration_secs": starting_delay + duration + sbw.FEEDER_SLACK_SECS, + } + for mode, init, name in ( + (sbw.BASELINE, "init.sql", "clickhouse.yaml"), + (sbw.BASELINE_MV, "init_mv.sql", "clickhouse_mv.yaml"), + ): + clickhouse = { + "experiment": [{"mode": mode, "server": "clickhouse"}], + "servers": [{"name": "clickhouse", "url": sbw.CLICKHOUSE_URL}], + "dataset": { + "name": "custom", + "init_sql_file": str(out_dir / init), + "paced_feeder": feeder, + }, + "query_groups": groups, + "data_ingestion_interval_ms": workload["data_facts"]["scrape_interval_ms"], + } + files[name] = "# @package experiment_params\n" + yaml.safe_dump( + clickhouse, sort_keys=False + ) + for name, config in (("e2e.yaml", e2e), ("victoriametrics.yaml", vm)): + files[name] = "# @package _global_\n" + yaml.safe_dump(config, sort_keys=False) + return {out_dir / name: content for name, content in files.items()} def render(workload): @@ -164,8 +236,6 @@ def render(workload): "data_facts": workload["data_facts"], "queries": queries, "paced_feeder_table": paced_feeder_table(workload), - "pilot_profile": pilot_profile(workload), - "pilot_e2e_table": pilot_e2e_table(workload), "promql_planner": { "metrics": [ {"metric": metric, "labels": labels} for metric in PROMQL_METRICS @@ -185,6 +255,12 @@ def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--manifest", type=Path, required=True) parser.add_argument("--out", type=Path, required=True) + parser.add_argument( + "--pilot-dir", + type=Path, + help="the workload's archived pilot plan (eval_table.json and planner " + f"configs): also write the pilot's run configs under {CONFIG_DIR}", + ) args = parser.parse_args() workload = json.loads(args.manifest.read_text()) rendered = render(workload) @@ -212,14 +288,12 @@ def main(): json.dumps(rendered["paced_feeder_table"], indent=2, sort_keys=True) + "\n" ) print(table) - profile = args.out / "pilot_profile.yaml" - profile.write_text(yaml.safe_dump(rendered["pilot_profile"], sort_keys=False)) - print(profile) - e2e_table = args.out / "pilot_e2e_table.json" - e2e_table.write_text( - json.dumps(rendered["pilot_e2e_table"], indent=2, sort_keys=True) + "\n" - ) - print(e2e_table) + if args.pilot_dir: + for path, content in pilot_configs(workload, args.pilot_dir).items(): + path = Path(EXPERIMENTS_DIR) / path + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content) + print(path) if __name__ == "__main__": diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index e514dca6..8f7345b7 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -1,9 +1,17 @@ """Tests for manifest-to-planner workload rendering.""" +import math import os +import random +import shutil +import subprocess import sys import json +import tempfile import unittest +from pathlib import Path + +import yaml sys.path.insert( 0, os.path.join(os.path.dirname(__file__), "..", "datasets", "fake_metric") @@ -11,6 +19,19 @@ import random_workload_artifacts as artifacts # noqa: E402 import random_workloads as workloads # noqa: E402 +import sketch_bench_workloads as sbw # noqa: E402 + +PILOT_DIR = ( + Path(__file__).parent.parent + / "datasets/fake_metric/random_workloads/seed-862/workload-01-pilot" +) +CLICKHOUSE = shutil.which("clickhouse") + + +def pilot(): + workload = workloads.generate_workloads(seed=862)[0] + files = artifacts.pilot_configs(workload, PILOT_DIR) + return workload, {path.name: content for path, content in files.items()} class RenderArtifactsTest(unittest.TestCase): @@ -63,29 +84,10 @@ def test_paced_feeder_table_preserves_all_manifest_data_facts(self): {"universe_keys": 10_000, "keys_per_series": 1_000}, ) - def test_pilot_profile_contains_only_common_queries(self): - profile = artifacts.pilot_profile(workloads.generate_workloads(seed=862)[0]) - - self.assertEqual(len(profile["included_query_ids"]), 7) - self.assertEqual(len(profile["excluded_query_ids"]), 3) - self.assertEqual(profile["data_ingestion_interval_ms"], 100) - self.assertTrue(profile["promql_query_groups"]) - self.assertTrue(profile["clickhouse_query_groups"]) - def test_archived_pilot_plan_reads_the_manifest_s_pilot_queries(self): # The archived plan is only valid for the queries it was solved for. workload = workloads.generate_workloads(seed=862)[0] - archived = os.path.join( - os.path.dirname(__file__), - "..", - "datasets", - "fake_metric", - "random_workloads", - "seed-862", - "workload-01-pilot", - "eval_table.json", - ) - with open(archived) as f: + with open(PILOT_DIR / "eval_table.json") as f: e2e = json.load(f)["workloads"][0]["e2e"] self.assertEqual( [(q["promql"], q["interval_secs"] * 1000) for q in e2e["queries"]], @@ -96,13 +98,120 @@ def test_archived_pilot_plan_reads_the_manifest_s_pilot_queries(self): ], ) - def test_pilot_e2e_table_is_consumable_by_existing_config_renderer(self): - table = artifacts.pilot_e2e_table(workloads.generate_workloads(seed=862)[0]) - e2e = table["workloads"][0]["e2e"] - self.assertEqual(len(e2e["queries"]), 7) - self.assertEqual(set(e2e["metrics"]), {"data", "data_total", "events"}) - self.assertTrue(all(query["interval_secs"] >= 1 for query in e2e["queries"])) +class PilotConfigsTest(unittest.TestCase): + def test_every_arm_feeds_the_same_data_and_schedule(self): + workload, files = pilot() + e2e = yaml.safe_load(files["e2e.yaml"])["experiment_params"] + vm = yaml.safe_load(files["victoriametrics.yaml"])["experiment_params"] + raw = yaml.safe_load(files["clickhouse.yaml"]) + mv = yaml.safe_load(files["clickhouse_mv.yaml"]) + + self.assertEqual( + [m["mode"] for m in e2e["experiment"]], ["sketchdb", "baseline"] + ) + self.assertEqual([m["mode"] for m in vm["experiment"]], ["baseline"]) + self.assertEqual(vm["monitoring"]["tool"], "victoriametrics") + self.assertEqual(raw["experiment"][0]["mode"], sbw.BASELINE) + self.assertEqual(mv["experiment"][0]["mode"], sbw.BASELINE_MV) + self.assertIn( + "prebuilt_output_dir", yaml.safe_load(files["e2e.yaml"])["controller"] + ) + + feeders = [ + e2e["exporters"]["exporter_list"]["paced_feeder"], + vm["exporters"]["exporter_list"]["paced_feeder"], + raw["dataset"]["paced_feeder"], + mv["dataset"]["paced_feeder"], + ] + for feeder in feeders: + self.assertEqual( + (feeder["workload_table"], feeder["seed"], feeder["metrics"]), + (str((PILOT_DIR / "eval_table.json").resolve()), 862, ["data"]), + ) + # The longest lookback (20 min) plus the freshness delay, then 10 min. + schedules = [ + (g["repetition_delay_ms"], g["client_options"]) + for config in (e2e, vm, raw, mv) + for g in config["query_groups"] + ] + self.assertEqual({ms for ms, _ in schedules}, {1_000, 20_000, 30_000}) + for ms, options in schedules: + self.assertEqual(options["starting_delay"], 1210) + self.assertEqual(options["query_time_offset"], 10) + self.assertEqual(options["repetitions"], 600_000 // ms) + self.assertTrue(options["align_to_interval"]) + + pilot_sql = [ + q["clickhouse_sql"] + for q in workload["queries"] + if q["support"] == "common-promql" + ] + raw_sql = "".join(files[f"interval_{t}s_baseline.sql"] for t in (1, 20, 30)) + self.assertTrue(all(sql in raw_sql for sql in pilot_sql)) + + +@unittest.skipUnless(CLICKHOUSE, "clickhouse binary not found") +class PilotMvMatchesRawTest(unittest.TestCase): + """The pilot's MV SQL answers what its raw SQL does, in clickhouse-local, + over 12 series sampled every 100 ms for 22 min.""" + + def test_mv_sql_matches_raw_sql(self): + _, files = pilot() + start_s, end_s = 1767225600, 1767225600 + 22 * 60 + rng = random.Random(3) + series = [ + (f"r{r}", f"s{r}{s}", f"j{r}{s}", f"l{r}{s}{i}") + for r in range(2) + for s in range(2) + for i in range(3) + ] + with tempfile.TemporaryDirectory() as tmp: + csv = os.path.join(tmp, "data.csv") + with open(csv, "w") as f: + for t in range(start_s * 1000, end_s * 1000, 100): + for labels in series: + f.write(f"{t},{','.join(labels)},{rng.paretovariate(2.0)!r}\n") + script = [ + files["init_mv.sql"], + "INSERT INTO data SELECT fromUnixTimestamp64Milli(ts_ms), region, " + f"service, job, label_0, value FROM file('{csv}', 'CSV', " + "'ts_ms Int64, region String, service String, job String, " + "label_0 String, value Float64');\n", + ] + for interval in (1, 20, 30): + for mode in (sbw.BASELINE, sbw.BASELINE_MV): + text = files[f"interval_{interval}s_{mode}.sql"] + for i, sql in enumerate(s for s in text.split(";\n") if s.strip()): + # Eval times past the 20 min warm-up, on every interval. + for end in (end_s - 60, end_s): + sql_at = sql.replace(sbw.END, str(end)) + script.append( + f"SELECT '{mode}/{interval}/{i}/{end}' AS qid, * " + f"FROM ({sql_at}) FORMAT JSONEachRow;\n" + ) + path = os.path.join(tmp, "script.sql") + with open(path, "w") as f: + f.write("".join(script)) + out = subprocess.run( + [CLICKHOUSE, "local", "--queries-file", path], + check=True, + capture_output=True, + text=True, + ).stdout + got = {} + for line in out.splitlines(): + row = json.loads(line) + mode, qid = row.pop("qid").split("/", 1) + value = row.pop("value") + got.setdefault(qid, {}).setdefault(mode, {})[tuple(row.items())] = value + self.assertEqual(len(got), 7 * 2) + for qid, by_mode in got.items(): + raw, mv = by_mode[sbw.BASELINE], by_mode[sbw.BASELINE_MV] + self.assertTrue(raw, qid) + self.assertEqual(sorted(raw), sorted(mv), qid) + for key, value in raw.items(): + self.assertTrue(math.isclose(mv[key], value, rel_tol=1e-9), qid) if __name__ == "__main__": From 50dd87499db937cd6b39ed5aebaece9217b621d2 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 20:23:46 -0400 Subject: [PATCH 21/25] test(asap-tools): preflight the pilot run configs Composes each of the four configs through Hydra and runs its runner's checks before any service starts: experiment config, paced feeder, and the client configs of each mode. Co-Authored-By: Claude Opus 5.5 --- .../tests/test_random_workload_artifacts.py | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 8f7345b7..0e443aa9 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -12,6 +12,13 @@ from pathlib import Path import yaml +from hydra import compose, initialize_config_dir +from omegaconf import OmegaConf + +from experiment_run_clickhouse import _check_clickhouse_paced_feeder +from experiment_utils import config as experiment_config +from experiment_utils.core import read_exporter_config +from experiment_utils.services.paced_feeder import check_paced_feeder_config sys.path.insert( 0, os.path.join(os.path.dirname(__file__), "..", "datasets", "fake_metric") @@ -151,6 +158,91 @@ def test_every_arm_feeds_the_same_data_and_schedule(self): self.assertTrue(all(sql in raw_sql for sql in pilot_sql)) +class PilotConfigsPreflightTest(unittest.TestCase): + """Each config through Hydra and the checks its runner makes before it + starts any service, from a copy of the config directory.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.cwd = os.getcwd() + shutil.copytree( + Path(artifacts.EXPERIMENTS_DIR) / "config", Path(self.tmp.name) / "config" + ) + workload = workloads.generate_workloads(seed=862)[0] + for path, content in artifacts.pilot_configs(workload, PILOT_DIR).items(): + (Path(self.tmp.name) / path).parent.mkdir(parents=True, exist_ok=True) + (Path(self.tmp.name) / path).write_text(content) + # Configs name their SQL relative to the runners' directory. + os.chdir(self.tmp.name) + + def tearDown(self): + os.chdir(self.cwd) + self.tmp.cleanup() + + def compose(self, name): + with initialize_config_dir( + version_base=None, config_dir=os.path.join(self.tmp.name, "config") + ): + return compose( + "config", + overrides=[f"experiment_type=random_workload/workload-01/{name}"], + ) + + def test_e2e_and_victoriametrics_configs_validate(self): + for name, modes in ( + ("e2e", ["sketchdb", "baseline"]), + ("victoriametrics", ["baseline"]), + ): + with self.subTest(config=name): + cfg = self.compose(name) + params = cfg.experiment_params + experiment_config.validate_experiment_config(params) + exporter_config, reason = read_exporter_config(params) + self.assertIsNotNone(exporter_config, reason) + check_paced_feeder_config( + OmegaConf.to_container(exporter_config.exporter_list.paced_feeder), + modes=OmegaConf.to_container(params.experiment), + parallelism=cfg.streaming.parallelism, + min_feed_secs=cfg.flow.steady_state_wait + + experiment_config.get_minimum_experiment_running_time(params), + forward_unsupported_queries=cfg.streaming.forward_unsupported_queries, + auto_discover_labels=cfg.controller.auto_discover_labels, + ) + got, _ = experiment_config.generate_controller_client_configs( + params, os.path.join(self.tmp.name, name) + ) + self.assertEqual(got, modes) + + def test_clickhouse_configs_validate(self): + for name, mode in ( + ("clickhouse", sbw.BASELINE), + ("clickhouse_mv", sbw.BASELINE_MV), + ): + with self.subTest(config=name): + params = self.compose(name).experiment_params + experiment_config.validate_experiment_config(params) + out = os.path.join(self.tmp.name, name) + servers = {s.name: s.url for s in params.servers} + modes = experiment_config.generate_clickhouse_client_configs( + query_groups=params.query_groups, + local_experiment_dir=out, + mode_server_urls={mode: servers["clickhouse"]}, + clickhouse_database="default", + ) + self.assertEqual(modes, [mode]) + with open( + os.path.join(out, "controller_client_configs", f"{mode}.yaml") + ) as f: + client_config = yaml.safe_load(f) + align = _check_clickhouse_paced_feeder( + OmegaConf.to_container(params.dataset.paced_feeder), + modes, + client_config, + experiment_config.get_minimum_experiment_running_time(params), + ) + self.assertEqual(align, 60) + + @unittest.skipUnless(CLICKHOUSE, "clickhouse binary not found") class PilotMvMatchesRawTest(unittest.TestCase): """The pilot's MV SQL answers what its raw SQL does, in clickhouse-local, From 02992797ec1b4674b9b1b6a6e464f7063eaa9193 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 20:54:14 -0400 Subject: [PATCH 22/25] fix(asap-tools): let VictoriaMetrics serve fresh samples -search.latencyOffset defaults to 30 s, so queries sent sooner than that after their window closes miss its last samples. Prometheus has no such delay. Co-Authored-By: Claude Opus 5.5 --- .../services/docker-compose.victoriametrics.yml.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asap-tools/experiments/experiment_utils/services/docker-compose.victoriametrics.yml.j2 b/asap-tools/experiments/experiment_utils/services/docker-compose.victoriametrics.yml.j2 index adf14db5..c47bec7f 100644 --- a/asap-tools/experiments/experiment_utils/services/docker-compose.victoriametrics.yml.j2 +++ b/asap-tools/experiments/experiment_utils/services/docker-compose.victoriametrics.yml.j2 @@ -19,6 +19,9 @@ services: # Raise the per-query caps so 24 h windows over many series aren't rejected. - "-search.maxSamplesPerQuery=10000000000" - "-search.maxPointsPerTimeseries=1000000" + # Serve samples as soon as they arrive, as Prometheus does; the default + # 30 s hides the end of any window queried sooner after it closes. + - "-search.latencyOffset=0s" {% if cpu_limit or memory_limit -%} deploy: resources: From aa047ecbce154032c43782e3aa44f25148fee3b9 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Wed, 14 Oct 2026 22:08:46 -0400 Subject: [PATCH 23/25] feat(asap-tools): archive saved plans for workloads 02-10 Each exported (sketch-bench f885d7e), solved, and converted by --planner saved like workload 01; none drops an RQE. Tests check every archived plan answers its manifest's pilot queries and every workload renders its run configs. Co-Authored-By: Claude Opus 5.5 --- .../seed-862/workload-01-pilot/README.md | 3 + .../workload-02-pilot/eval_table.json | 448 ++++++++++++++++++ .../workload-02-pilot/inference_config.yaml | 79 +++ .../seed-862/workload-02-pilot/plans.json.gz | Bin 0 -> 2494 bytes .../workload-02-pilot/streaming_config.yaml | 89 ++++ .../workload-03-pilot/eval_table.json | 392 +++++++++++++++ .../workload-03-pilot/inference_config.yaml | 80 ++++ .../seed-862/workload-03-pilot/plans.json.gz | Bin 0 -> 2306 bytes .../workload-03-pilot/streaming_config.yaml | 89 ++++ .../workload-04-pilot/eval_table.json | 395 +++++++++++++++ .../workload-04-pilot/inference_config.yaml | 77 +++ .../seed-862/workload-04-pilot/plans.json.gz | Bin 0 -> 2331 bytes .../workload-04-pilot/streaming_config.yaml | 89 ++++ .../workload-05-pilot/eval_table.json | 445 +++++++++++++++++ .../workload-05-pilot/inference_config.yaml | 79 +++ .../seed-862/workload-05-pilot/plans.json.gz | Bin 0 -> 2491 bytes .../workload-05-pilot/streaming_config.yaml | 89 ++++ .../workload-06-pilot/eval_table.json | 398 ++++++++++++++++ .../workload-06-pilot/inference_config.yaml | 79 +++ .../seed-862/workload-06-pilot/plans.json.gz | Bin 0 -> 2323 bytes .../workload-06-pilot/streaming_config.yaml | 89 ++++ .../workload-07-pilot/eval_table.json | 445 +++++++++++++++++ .../workload-07-pilot/inference_config.yaml | 80 ++++ .../seed-862/workload-07-pilot/plans.json.gz | Bin 0 -> 2496 bytes .../workload-07-pilot/streaming_config.yaml | 89 ++++ .../workload-08-pilot/eval_table.json | 392 +++++++++++++++ .../workload-08-pilot/inference_config.yaml | 78 +++ .../seed-862/workload-08-pilot/plans.json.gz | Bin 0 -> 2307 bytes .../workload-08-pilot/streaming_config.yaml | 89 ++++ .../workload-09-pilot/eval_table.json | 398 ++++++++++++++++ .../workload-09-pilot/inference_config.yaml | 81 ++++ .../seed-862/workload-09-pilot/plans.json.gz | Bin 0 -> 2309 bytes .../workload-09-pilot/streaming_config.yaml | 89 ++++ .../workload-10-pilot/eval_table.json | 445 +++++++++++++++++ .../workload-10-pilot/inference_config.yaml | 77 +++ .../seed-862/workload-10-pilot/plans.json.gz | Bin 0 -> 2487 bytes .../workload-10-pilot/streaming_config.yaml | 89 ++++ .../tests/test_random_workload_artifacts.py | 45 +- 38 files changed, 5304 insertions(+), 13 deletions(-) create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-03-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-04-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/streaming_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10-pilot/eval_table.json create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10-pilot/inference_config.yaml create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10-pilot/plans.json.gz create mode 100644 asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-10-pilot/streaming_config.yaml diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md index d1732bdb..321063f2 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-01-pilot/README.md @@ -14,6 +14,9 @@ roll-up) and the three quantiles from one per-series DDSketch. Top-k heaps over 500 series read the curves at their first 1,000 keys (the table's `assumptions`). +`../workload-NN-pilot/` hold workloads 02-10's plans, made the same way +(sketch-bench f885d7e: queries reading the same RQE share it). + Regenerate, with `SB` a sketch-bench checkout at the table's `sketch_bench_revision`, from this repository's root: diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/eval_table.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/eval_table.json new file mode 100644 index 00000000..24633c35 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/eval_table.json @@ -0,0 +1,448 @@ +{ + "inputs": { + "workload-02.json": "0e310ace0829cf327f912ad3885a87555bcbadd742c73faa99224103b7542bd8" + }, + "plan": "ProjectASAP/ASAPQuery#879", + "schema_version": 1, + "sketch_bench_revision": "f885d7e9a99dd435683a7dcd66516a36b3ac02ab", + "workloads": [ + { + "dataset": "random/seed=862/workload-02", + "e2e": { + "metrics": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ], + "samples_per_sec_per_series": 10, + "type": "gauge", + "values": { + "dist": { + "pareto": 2.0 + }, + "value": { + "keys": 10000, + "zipf": 1.1 + } + } + } + }, + "queries": [ + { + "interval_secs": 5, + "promql": "sum by (region, service, job) (sum_over_time(data[5m]))", + "rqes": [ + "random/seed=862/workload-02/q01-sum-fine/keys/300s" + ] + }, + { + "interval_secs": 5, + "promql": "sum by (region, service) (sum_over_time(data[5m]))", + "rqes": [ + "random/seed=862/workload-02/q02-sum-coarse/keys/300s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region) (quantile_over_time(0.75, data[100s]))", + "rqes": [ + "random/seed=862/workload-02/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service) (quantile_over_time(0.95, data[100s]))", + "rqes": [ + "random/seed=862/workload-02/q04-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", + "rqes": [ + "random/seed=862/workload-02/q05-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "topk by (region, service) (4, sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-02/topk4_q06-topk-sum/keys/60s" + ] + }, + { + "interval_secs": 60, + "promql": "topk by (region, service) (4, sum_over_time(data[20m]))", + "rqes": [ + "random/seed=862/workload-02/topk4_q07-topk-sum/keys/1200s" + ] + } + ] + }, + "rqes": [ + { + "assumptions": [], + "capability": "sum", + "covered_groups": 200, + "covered_max_N": 150000.0, + "covered_min_N": 150000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service", + "job" + ], + "id": "random/seed=862/workload-02/q01-sum-fine/keys/300s", + "instant": false, + "interval_secs": 5, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 200, + "keys_per_window": null + }, + "lookback_secs": 300.0, + "max_N": 150000.0, + "max_covered_share": 0.005, + "metric": "data", + "min_N": 150000.0, + "min_covered_share": 0.005, + "queries_per_instance": 1, + "query_id": "q01-sum-fine", + "range": "300s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "sum", + "covered_groups": 20, + "covered_max_N": 1500000.0, + "covered_min_N": 1500000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-02/q02-sum-coarse/keys/300s", + "instant": false, + "interval_secs": 5, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": null + }, + "lookback_secs": 300.0, + "max_N": 1500000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 1500000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "q02-sum-coarse", + "range": "300s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-02/q03-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q03-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-02/q04-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q04-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-02/q05-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q05-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-02/topk4_q06-topk-sum/keys/60s", + "instant": false, + "interval_secs": 1, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 60.0, + "max_N": 300000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk4_q06-topk-sum", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 6000000.0, + "covered_min_N": 6000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-02", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-02/topk4_q07-topk-sum/keys/1200s", + "instant": false, + "interval_secs": 60, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 1200.0, + "max_N": 6000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 6000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk4_q07-topk-sum", + "range": "1200s", + "stream": "data/value" + } + ], + "schemas": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ] + } + } + } + ] +} diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/inference_config.yaml new file mode 100644 index 00000000..3d590028 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/inference_config.yaml @@ -0,0 +1,79 @@ +cleanup_policy: + name: circular_buffer +metrics: + data: + - job + - label_0 + - region + - service +queries: +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 60 + query: sum by (region, service) (sum_over_time(data[5m])) + planned_subquery: sum by (job, region, service) (sum_over_time(data[5m])) + query_time_aggregations: + - operator: sum + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 60 + query: sum by (region, service, job) (sum_over_time(data[5m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[5m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + num_aggregates_to_retain: 59 + query: topk by (region, service) (4, sum_over_time(data[1m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 4 + num_aggregates_to_retain: 20 + query: topk by (region, service) (4, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[20m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region) (quantile_over_time(0.75, data[100s])) + planned_subquery: quantile_over_time(0.75, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region, service) (quantile_over_time(0.95, data[100s])) + planned_subquery: quantile_over_time(0.95, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region, service, job) (quantile_over_time(0.99, data[100s])) + planned_subquery: quantile_over_time(0.99, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/plans.json.gz b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-02-pilot/plans.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..25193416a594c2d3034de707d448f483a6686398 GIT binary patch literal 2494 zcmZ|NX*3(?8V7J@)TOtZU2Q3$O)08XM$E)e30kr5wG6E-wWOLV8r3N}wMC>=F|mtK zwDwYj(vsGm#4=TTVk@eaij>Gzqvzh?-19rn^FQzV;dwv24=N@oV z4RJFtfM-74#d^X=>H+uQB(=-0Xpu!R?QH6o3GB=0pxQ}@$v=xXKFjM;RK(qA2<(yL z^UJ+I5h9BclNA;TIN=OoiEV}bny19onBktkO=j*0=z#)tlyBJAB5Ho zY?Y>AiU@H*G&$R?)LY4sGu`=|52h=L(rLDE9mk)0JQec>406itw5 zJ^qX+qL1(Ka>*p+cIidn?Sn!qd@UswPP#R!x+<_8B0d{{8$_2&Q{80l9*4IvR+dRR z{RWzB%L~(!e#j@)>fDr^_Ulz~lw9}sfo=LDah=`BFj<>{(G()*lU8Y?_^SCF0s`lq z@}3>*{zweJ@;E;iL6h@!bW5Oh>D@MWgX5WL+_JtU7(PFehL{)0;t$>~%VQ zoCY6I4Ia4Aba=70kEfHoc_emewb-HlgRb|}qw3Qw*R-TkDE2KO8D_~rs_o-QRl}F! zIbYwNma-Z$h+Xrye(chn21a$lRfxM<0$GlNO^�}TgA4d(qm zLD~>c!)J(OKhxIW9~U`XEYZL9R>gOo72&0>V|msB?ev?Kh6Q?QI%ryBjigOQLsaSQNehGFWB?kf*d`{0f=ITf& z=(!H0r;-*VQaCW+HPa$R=T(g}tnU5;`A`AXGNZV$hue%j;qNbb!nctFldEQ8*Vc@s zuF?q22l8@IFLa$p%()Cfj9yNMq|HM?B@yk|mKmS-L5FCtK#}OMtBd+1^Q;nb`!EsX zux!5i zngV(=>_e^bbU0+`RFqz-Tq}9F8Q2W0fJPbp?PPq3{LcvfcysBqS`3demm3@9qH*2f z4FgFAQVU5(2)m@4nS`+5SUj2nEREp^=onzIK;}*`7|geaLn392E4+G5GHTK<2t>kYV&*Q8Kz+ zGM4iD*{f$ZMH4exqlr|~F0V5tx#We*l}Ym1@N33BLMT32eWRVojKTbc-7D+rz*8Vt zaUbSKCCwSEXzvUbHTYeJ(rjgQc&Zjyu`=d}AoxBe3pgY2Eg0viLbAepq2|H24FA~A zx$Xf!0QW!&fU_ce*QA)Y*00_Rd&s9Pq~LD!mr!t&>`tK7bUh6BYR05bV?as!74@#y z9AoDdm|Oojw*r%|FYkXhR+Ti1rmtb!?T99?@ODeBY{@5g5OeqG3Q=q9hvKTj+i(bi z)e{6^+nv!uf2!EhLXu`HQ9JtIm!PwLtR*IAmHUA4?v!zoog=zU}sTX?UFRqbu_@6LbqTBDuS(%(tL7 zvN}@L&d5`Pm3F%BwkQp$dE@!*@6r|i+dcGQU8~oLR{(ktCJbVX6+B^EdJd6|mQzyZ zGuh)^<78$J3`=~zUE`!(UcZ{WCO>NQi98{AL&5ld;uvsU0J0P7XtW`AuP8vK=H0!Q z-_ApuWQHVewNDafGxVJ)=xNRE6^Q@~MSU|-lXaoHQGjuyop5`V_!Dj~9wwb1YmD1Z zy5zY&j#vi65t*c2UWO*`$b`9?r0vm){~X<%xPQX`9ZgU#X~Gf9TXDom(k?HUNjo`L z%zdt^(I1ni5Xs4I(=5_CjzIY8U{2#u6 znM`Nvfwz0jHZ4*f=;Fm@cnR`LmwKj?*zGu|U6MI2St*8``2u6Nxz;~`w&b9#L@gRE zg;keM&D0JUx&+cqSN(3;_7*Od+!GJmC;rA?TZ5Kc{rj1cX4`XVcdHtUb7@u*6vcXZ z@#*p>=1w*I>$s!SU5xaU#oD!Ik6NyHD0F?{O-)$cT8C?c_y+2koO)aH5`$kM=*IFB6oSc5vsY8+^+b<9d>Cu(KwDIcd{oS7v==QE!%4vUxWC#()7 zyzK6Of*M$;P_y@3tR>nq3+-wuJYwx!ZrHNV6igQkUVqwZSu)zdS|A3v6kPdW({?Do z{Fvj#cn-GyId`7vk0>7v$m}yK&Q7IrF$a-W1jY2dDT~G^83ew}9I-8a(&%1dGw%ptnY0ZsM{ZEVx)HP}Q5$WrU^zIv| ztcgL^W`5iFpWNof{yc@F<6jES$bPga(lFLEj|$-uL(Xd%6hCM`+^Y%Z%=11y%aj{$ zEp@DPckG)iC(N%5#;K8{9Is81j&asbsXg(EGh)V82eNhc(Oq);Eb{e7bEob72cCwn z9USx(nzjFSyE*u%I&&gu((x0y-0Cr|V`983PDwMugWsTsToiudZpi0d?9AOOZN8ubEba#2y zUm>XZy>EYV{YA&v;@)^lU)|R9%xQISl#^FCBh7}N5y9tCzQp{j1%B4|J z9{&zphlyi*d|LumH-vV?>3dee&YOM3r*;_y$-`dg7c54}C{Zlvp1IPtRUI3Da%Qh6 zJam!x@T~AreMnC4rgrpQ`cvt#(zaFabA8lIuD&sK!IIT7(H%%1NY!XKI1@ZbvTkIU)~6Wd^8{8rls!MfZh};ObI;9DIkF6HuB}{*H7f z>k^Q``}H*EP_cJ3*Ku@tnPXKbG({i6!w#Dwu3)q7U3e`At5ku}{SFl!8YsF(OR4Q* z3kQmJDp~B)?FC92m4LVDV4V$_`#AF##O^m^ zNlQq~`JPJN-Le~D?yv5zGso~wuk@}d*MsZ9523*@fpkOX444&uGNL{6staz`0cY*) z=Rfq}TFB`NtuRm{Kn1IX)!Ja!y}3j4}(27{)e8&8O-G=Bt1fqzUR7Q%KD44lM>%|My+c;QYe-WnIL|lNq z6YwyXiivq~o25wS1kXnj3 za2;^s1$bU$oxdZrEaC?M%p2~V{T><88L^#9rUc(de(IzxJ}c&m7~)x^|i z??~V!M+b`ogu?-F z00^);0w6@m62NO)?UI91Qf+-$nBw`h{_o{79@qUM=Wb;pft3&rO(YAvplgs4cZ4Z6 zY~rbk1O&j`=VUaeMO+^POxRD^hOfK9yQqg9bJoL}Tt>!3zZRI1L?xzOr(8Iwp!EIm ztv?hw0RFuQ+!zLpfR-L^lDF-m?B`o-I%ywJ64pGRq@z=9a(U|@V-#a8f5)Pw(;z^g z5C#o_0DClrvC=<~!a6CP6yh79Ch6^nnL{cRgvnSW!o`O70OR|M1#*!HmQAA>JF{B}qHCK$n7_tvnmWqauY}tlH zQp%FaSjOIhkbRgKGSb}UcD--T=a1){@Ao|CJbyfpL=fn2?OtyVroWGyZ;+aIke@Hx zQm%!~RJ();Gl5ig?>#%CY0wOv)&;d4y%c<r)ahg&dk;P z5a=DtMC+CH#wVqT1PmqI;q9&AW>gp@@TT1W>7#$nxzCU=+iJx!w1&B!^Vzk~u|=lg zX3ycZ&zEma$)a9QdeO`6Q%D|OF0+Zm>C)_+$`#C+odY6;AQ?Ad{$(QAG zJ8^IB1|mIak0?D5?M?WYPZ~0`_RZ|k6Cq~Mp~KXo^!+mUg~6pc$|aYa9MNHVyx;>% zPg{a0X;SAZ>YL=5EEDa-;&f|`M~QAhu3iKr%|)@2D%xhy;`@dw%115@tc#OBJ6ys< zhK}hUY#S}iInm*GAuGLM4ZpmoqA5>Id4hbHynYiOY-f>s3+*z<^O#7ZY1P@8d(eum zAg{lxk8P4_?v@y<6WCarznC+wPp=@A;MMH5!gcS69M0OhCOob=W2b9cunhIhunula z+NeU`zDmHnYxMsz!ZkDXUb?Qk+`s9gGM#bk5ZEe2frQ~Jx+oyHBm9u$@$FBA}m?*$OPggx!dnkpdaATu+@)LO>Wm}PdT zrp&<;9cq`|i)c!hXgfAk#pk2W;c|C9=N^CcMYU}nY{O^K37IIr7V#^z8TTOG=N2ZW zYnuEWrINBr5Y^ z14B{4u9EgVKgPx@Xc;=RY1|K+VkqLGR8&VF3PZ;*&7pe85BVv_XjIXzZJn6WyjRC1 zI#tra-wn8-)YQC!zdi(b&lalY*l5PNCT~L5ygLjIk8{nv?nY%?yS8{YzWc#)r3Yp< zCkwfJ>KO5|#mGB+A4OhYWwtZoNz#|A8GTX>NfpJ86vnFr;5^jtQ-@Gi==O5WGVV~t zb4Yu@(PvSwuHM*)n=N6;l3NsX_}3@Pm@7t>jFJjI9eqEZ%h1X5Cnt)_Xoe{+@B6^(g6OXvQi3ebugB8UYq`mQJ{v@sLt1O2h!qM z`Xs!Q%{q;$1T=vO&aZ5Sk>Cjm?<$NN{vVF;)E_&I6x#ozpH&!soDX*Z(He6Ap=c5m zXO+bA(F$V;=i$igjgp3R@_dO3mnQh8f(?OP)6rlYcp(2i7!K^wt0#ngUcq^ztE|?( zd)WiedcTv~xV)HNcx5oApITuJZ_{-V7nEvuf(ix{v2-+T;I8l=A;cd&O~om`su*$G;|Q^3g1c;)c}zF z{2f{{5-C6m@HJWv_X8JO-71ccjmT8!b35aaJBpBaJs3)TYw7Z*Fs2ml6jL9HUYu#r_URWZ;J?%iN_hE~V(Sw1#Z;(m$eFUaLdmrXp($rM5@ODgkm^g0Ifs-xllzF2oXbjB zL@~LgVc9awwVC7Vp`XX&_u%n-d>*gIJ6!Fp{3zZ` z6sf15Apf|N@NRK(Jj=y#waDdW%p9X?wb5sob9Z`)u*PZ@U1!sihY1g=R*RUlhsF<3 zWIsY3Jw5s}#j97XmfoJq9I5wIke2wjcG$h%6RskkYVPh~93?*e0HabuGgoQjNsqxI zHE6+_BGxhDQ+ffieX~u0Ruwm3EH6)J4um zFV#{;DG3>1A}&}#!u;;YTjk(Lf&79fQ$vC2N}&T2leoc!R2LgwroZT_xj=iJO*fQ4 zUi*lcnv7UX8BD}t&`>Ol7qb zMo`}7U%3VS*O|cuKK@0%v-cHcI0h*B+rz$PSjpQv z;5&9z{w{gGBKXA`pXxKE>BGxEh$pBw{9UaMWT2~w{}xRsi(<-$!m?i&VEdY84eX)| z&8$gfycR*^>SYNj;3TF~Lpwf0uO?t2+G+YFhZbhgq-1$?B{_d*hN%{ef;($ZysLVZ$WO2}@KzpbC+)!G<^y-{p4 zu<7zw_z@l%;SazwfG94=W<~%}bLN=f!Lsk!s>c0$+#H1MDq}4)h`(y!yv0J+9{qWw z{en;U92fSr%7-N#M!d`pHn`qBRNkE0iD*eouu!gL_$Ipp{^?@y+|lW(cl@H$#gXnG zHuhYqn3@k1NY|?&bAGe=8|0)($+GxB%R7oA&S3I@6h3JDtS`4fZPU&CO2jvq)BGYG zWqBpi?e|jpqwIm%xzzXBB^@H`*aU2F3yol4(x&?PyOJpR&C_Gp0lT`N0+ z;&(~e72I@w+MIJ}m!ZZ%eAj)4oY%wR#fl;$d>i6fDL<1~DI1o@SzblCIkc5lbv~(( zxWcmZ@=5MK_P&+CuatAI!4BOQ_sZjE5c}#KG^C`n4;t4f-ptRd1Y7+wuq`p{bU#6Z z&>$x+_wxDXM81an0jjM5mnn`OQR0#X4hKlJ`Neuqw6|FS!&=(wB%|jq2FPFScFqAk zYz^t|*FXqohR11438SONi;0YYeU20Ln zo-25YgkLSRH945z^8EV89ARssRYwX5!3S&O}M8q~AO*A>^ zQ_N0QY9-w2xJqGl+@sVj+^}6sCv)8?dRl3$_@59KP~%DLW*+X=IHkWGAZ}nmQ~|ov zk9f+D)fQfzpp3%m{`+l4e)Om=<2*h+=h0*tI*(v=q3=+D~)2e7?i?rLo z?|r0mV{IT66^!_xxtugjb9||qP67v zaHL45ONnv^kJC>3b0_zj-Yj~{+w<~D_7$A}$9NAYDg-jBugp{%Z#hUDbKLl)a>Htu zh)`U&DhqbcGs&#KzwRtYr7cO z;F?LRP@}SGb8&I4ukYq^Am}OvGInwO2al`N^Z)<= literal 0 HcmV?d00001 diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/streaming_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/streaming_config.yaml new file mode 100644 index 00000000..3d3b4074 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-05-pilot/streaming_config.yaml @@ -0,0 +1,89 @@ +aggregations: +- aggregationId: 1 + aggregationSubType: '' + aggregationType: DDSketch + labels: + aggregated: [] + grouping: + - job + - label_0 + - region + - service + rollup: [] + metric: data + parameters: + alpha: 0.1 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 25000 + windowType: sliding +- aggregationId: 2 + aggregationSubType: sum + aggregationType: MultipleSum + labels: + aggregated: + - job + - region + - service + grouping: [] + rollup: [] + metric: data + parameters: {} + slideIntervalMs: 10000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 10000 + windowType: tumbling +- aggregationId: 3 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + - service + grouping: + - region + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 80 + width: 4096 + slideIntervalMs: 60000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 60000 + windowType: tumbling +- aggregationId: 4 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + grouping: + - region + - service + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 160 + width: 1024 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 3000 + windowType: sliding +metrics: + data: + - job + - label_0 + - region + - service diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/eval_table.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/eval_table.json new file mode 100644 index 00000000..5aac84bb --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/eval_table.json @@ -0,0 +1,398 @@ +{ + "inputs": { + "workload-06.json": "35bad66b98e305783fb612a45122e57aee7b0c6c96336ddc45e6e890e87d3ef1" + }, + "plan": "ProjectASAP/ASAPQuery#879", + "schema_version": 1, + "sketch_bench_revision": "f885d7e9a99dd435683a7dcd66516a36b3ac02ab", + "workloads": [ + { + "dataset": "random/seed=862/workload-06", + "e2e": { + "metrics": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ], + "samples_per_sec_per_series": 10, + "type": "gauge", + "values": { + "dist": { + "pareto": 2.0 + }, + "value": { + "keys": 10000, + "zipf": 1.1 + } + } + } + }, + "queries": [ + { + "interval_secs": 5, + "promql": "sum by (region, service, job) (sum_over_time(data[5m]))", + "rqes": [ + "random/seed=862/workload-06/q01-sum-fine/keys/300s" + ] + }, + { + "interval_secs": 5, + "promql": "sum by (region, service) (sum_over_time(data[5m]))", + "rqes": [ + "random/seed=862/workload-06/q02-sum-coarse/keys/300s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.50, data[100s]))", + "rqes": [ + "random/seed=862/workload-06/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service) (quantile_over_time(0.50, data[100s]))", + "rqes": [ + "random/seed=862/workload-06/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region) (quantile_over_time(0.90, data[100s]))", + "rqes": [ + "random/seed=862/workload-06/q05-quantile/values/100s" + ] + }, + { + "interval_secs": 2, + "promql": "topk by (region, service) (4, sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-06/topk4_q06-topk-sum/keys/60s" + ] + }, + { + "interval_secs": 60, + "promql": "topk by (region, service) (8, sum_over_time(data[20m]))", + "rqes": [ + "random/seed=862/workload-06/topk8_q07-topk-sum/keys/1200s" + ] + } + ] + }, + "rqes": [ + { + "assumptions": [], + "capability": "sum", + "covered_groups": 200, + "covered_max_N": 150000.0, + "covered_min_N": 150000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service", + "job" + ], + "id": "random/seed=862/workload-06/q01-sum-fine/keys/300s", + "instant": false, + "interval_secs": 5, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 200, + "keys_per_window": null + }, + "lookback_secs": 300.0, + "max_N": 150000.0, + "max_covered_share": 0.005, + "metric": "data", + "min_N": 150000.0, + "min_covered_share": 0.005, + "queries_per_instance": 1, + "query_id": "q01-sum-fine", + "range": "300s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "sum", + "covered_groups": 20, + "covered_max_N": 1500000.0, + "covered_min_N": 1500000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-06/q02-sum-coarse/keys/300s", + "instant": false, + "interval_secs": 5, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": null + }, + "lookback_secs": 300.0, + "max_N": 1500000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 1500000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "q02-sum-coarse", + "range": "300s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-06/q03-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q03-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-06/q05-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q05-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-06/topk4_q06-topk-sum/keys/60s", + "instant": false, + "interval_secs": 2, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 60.0, + "max_N": 300000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk4_q06-topk-sum", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 6000000.0, + "covered_min_N": 6000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-06", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-06/topk8_q07-topk-sum/keys/1200s", + "instant": false, + "interval_secs": 60, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 1200.0, + "max_N": 6000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 6000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk8_q07-topk-sum", + "range": "1200s", + "stream": "data/value" + } + ], + "schemas": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ] + } + } + } + ] +} diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/inference_config.yaml new file mode 100644 index 00000000..d31f2ec0 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/inference_config.yaml @@ -0,0 +1,79 @@ +cleanup_policy: + name: circular_buffer +metrics: + data: + - job + - label_0 + - region + - service +queries: +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 60 + query: sum by (region, service) (sum_over_time(data[5m])) + planned_subquery: sum by (job, region, service) (sum_over_time(data[5m])) + query_time_aggregations: + - operator: sum + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 60 + query: sum by (region, service, job) (sum_over_time(data[5m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[5m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + num_aggregates_to_retain: 30 + query: topk by (region, service) (4, sum_over_time(data[1m])) + planned_subquery: topk by (region, service) (4, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 4 + num_aggregates_to_retain: 20 + query: topk by (region, service) (8, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (8, sum_over_time(data[20m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region, service, job) (quantile_over_time(0.50, data[100s])) + planned_subquery: quantile_over_time(0.5, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region, service) (quantile_over_time(0.50, data[100s])) + planned_subquery: quantile_over_time(0.5, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region) (quantile_over_time(0.90, data[100s])) + planned_subquery: quantile_over_time(0.9, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + parameter: null diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/plans.json.gz b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/plans.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..c91f5b9dfedd03f28897bb85f2597c1bcb8f949a GIT binary patch literal 2323 zcmZwFc{J2}9|v$z8M(}_hfp+Qi9(GvWE&#}$<8QSC~FkiVnk-RVMggP+1C+63s*#4 zBf43#WXQGTu@23Qt!tUF&dhVW_i>(_^PJZopL5=y^L_vG{XlUbQ093`ATKv0$m>=Z zEHLc$EuO^!cZV^g1d^ND;miirO#T*FAzt7SRjy5*zoGvgRf7vY{_$t^oZXG(Bj)(v zchPHv zKbRZeVk$BibrMYLYV@KjbB#eyzD6{gTfR*FIC}T0wj>M{U=h6?rRHW0!!=%( zvaGCgYF8HF>MG|oh-k<9kB`pQU9BhpTqI@kyEBw#S-Zd^i-Etr>G~0dLdu~qz8A`pJae4z8oU1xf?(mK4G0Uua zn<7shYaQ3>-Aegd>n7%8K33zyot>c@uI79^5e_w3c(A;!X^TvwT;*PYLrM(3y%d3mP_7UUWRJ|?A`F#{vlz0_5#Kj9X( zO$6;KqMVAvyQg)QuI-8tEnUy!Dl+WUNH{OuRI6c~34yskX!0wKDv~2vhp?}z+|GI5 zXDBhbFq^ytyL_vz=&*9rhzlwF@sox=M;)80>%tI{3^v38W!3e&diA_>@95^HLOtrz z&zl4FxbfFkA;UFemnjp1HAOb!)Lq|}24M%N`}5VUJL>1GVQUPfxQ0wuuZKui#jY2k z1o|C3E8==)uo+n^7@N_d;NWrOT)hyg(S7nXlYLam#`DXfa&GqL@F$!K6Ad-D^XLy* z-FHF_b!m^YnSRARS|)f2*(hu4BT zxTOrgRRPA$)7ZfrjaL8LQDxPU6}L?^l9vafz)zut>2b-7owRjo1iN}mn-tc^$r&bm_>?92~5$0-#-r2 zv!#x|I(oc}k71;nF8tS6ObSPJud*7iwMj+fSEgGKeVPiAGUqLi`qQfPdP21n6q^Xh zE5x+Xue`@GZaW*mT;p(=RQ;pisx1^6$-(_MLbN)<7LA$e1tt(26MSBe=0rtJO9xB znbNjHl1tibO73N9V`p93=i1Ou+h?;`L3NMgHf|JlNGo<0oBoMthgSv6JXbXMq9}3s@4q|tAL4|ljE>5NEu`v0f0a7tr+P8ecUrl{bW6R3*~zN>Tp(Zhd0Y} zpI8mwKDlEBJ+3lAs!BL2TyTS32wWUk9A-T;$eF(!RTKQWaV1zN?@8k=Mu@#7CgwuG%~R5 zn|1)h7p#@>D2W%UE?&~$7pieXWWgi|9AO5g} zkZKj;1xR3t-`031A*L8Y;-6255iW|M#O*PH)IsZtV4^=n|Ez?OJ1KH}-yTGYO@L3T z&LhHG==b{%5Tyo>JO<*W@xARAW5XTS)x%#-|3M<^s(BcJVJVcv!`pJuUhqI0;^GhPfB)O{qbL_>g$I z|1^hkkSJ>+f>)5RQaxh4Bq6ZH?`X_PKu2vGZ!{O8aKMo=zcS<(pk@h;DTtk(&Z;W3wX-AXcmP?!-AJ_Pzp z@;{&An8eD9^LNj{QDr}CS$DTzSa{|6#W_i90NzqX5jj}gasTflT)FOWu&jLk*YX1a z6+wxzglM@u{o(r`$I_ED$1|gKqV5Cfr~ZEt<&l>7_qI2!jX}KG0Hzp9=ig3_cfakOwIyi;3Fj!O(k6^OX_qF}+Ass84 zDEj}}rVSK9%E=IM6cDVIda k6d$bo0`>;>p){O6Oy;hu@bK_(xqLjkZjX3NYYy=I2jl{I%m4rY literal 0 HcmV?d00001 diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/streaming_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/streaming_config.yaml new file mode 100644 index 00000000..38466937 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-06-pilot/streaming_config.yaml @@ -0,0 +1,89 @@ +aggregations: +- aggregationId: 1 + aggregationSubType: '' + aggregationType: DDSketch + labels: + aggregated: [] + grouping: + - job + - label_0 + - region + - service + rollup: [] + metric: data + parameters: + alpha: 0.1 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: sliding +- aggregationId: 2 + aggregationSubType: sum + aggregationType: MultipleSum + labels: + aggregated: + - job + - region + - service + grouping: [] + rollup: [] + metric: data + parameters: {} + slideIntervalMs: 5000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 5000 + windowType: tumbling +- aggregationId: 3 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + grouping: + - region + - service + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 120 + width: 1024 + slideIntervalMs: 2000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 2000 + windowType: tumbling +- aggregationId: 4 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + grouping: + - region + - service + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 160 + width: 4096 + slideIntervalMs: 60000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 60000 + windowType: tumbling +metrics: + data: + - job + - label_0 + - region + - service diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/eval_table.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/eval_table.json new file mode 100644 index 00000000..fe799b3f --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/eval_table.json @@ -0,0 +1,445 @@ +{ + "inputs": { + "workload-07.json": "b4f2431b6abad97dc834a1fd9bc27c9c008ce66efb6eaff79155063773ae23da" + }, + "plan": "ProjectASAP/ASAPQuery#879", + "schema_version": 1, + "sketch_bench_revision": "f885d7e9a99dd435683a7dcd66516a36b3ac02ab", + "workloads": [ + { + "dataset": "random/seed=862/workload-07", + "e2e": { + "metrics": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ], + "samples_per_sec_per_series": 10, + "type": "gauge", + "values": { + "dist": { + "pareto": 2.0 + }, + "value": { + "keys": 10000, + "zipf": 1.1 + } + } + } + }, + "queries": [ + { + "interval_secs": 20, + "promql": "sum by (region, service, job) (sum_over_time(data[10m]))", + "rqes": [ + "random/seed=862/workload-07/q01-sum-fine/keys/600s" + ] + }, + { + "interval_secs": 20, + "promql": "sum by (region, service) (sum_over_time(data[10m]))", + "rqes": [ + "random/seed=862/workload-07/q02-sum-coarse/keys/600s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.99, data[100s]))", + "rqes": [ + "random/seed=862/workload-07/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[100s]))", + "rqes": [ + "random/seed=862/workload-07/q04-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region) (quantile_over_time(0.50, data[100s]))", + "rqes": [ + "random/seed=862/workload-07/q05-quantile/values/100s" + ] + }, + { + "interval_secs": 2, + "promql": "topk by (region) (4, sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-07/topk4_q06-topk-sum/keys/60s" + ] + }, + { + "interval_secs": 60, + "promql": "topk by (region, service) (8, sum_over_time(data[20m]))", + "rqes": [ + "random/seed=862/workload-07/topk8_q07-topk-sum/keys/1200s" + ] + } + ] + }, + "rqes": [ + { + "assumptions": [], + "capability": "sum", + "covered_groups": 200, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service", + "job" + ], + "id": "random/seed=862/workload-07/q01-sum-fine/keys/600s", + "instant": false, + "interval_secs": 20, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 200, + "keys_per_window": null + }, + "lookback_secs": 600.0, + "max_N": 300000.0, + "max_covered_share": 0.005, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.005, + "queries_per_instance": 1, + "query_id": "q01-sum-fine", + "range": "600s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "sum", + "covered_groups": 20, + "covered_max_N": 3000000.0, + "covered_min_N": 3000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-07/q02-sum-coarse/keys/600s", + "instant": false, + "interval_secs": 20, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": null + }, + "lookback_secs": 600.0, + "max_N": 3000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 3000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "q02-sum-coarse", + "range": "600s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-07/q03-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q03-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-07/q04-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q04-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-07/q05-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q05-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "topk", + "covered_groups": 4, + "covered_max_N": 1500000.0, + "covered_min_N": 1500000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "topk", + "grid_K": 2500, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region" + ], + "id": "random/seed=862/workload-07/topk4_q06-topk-sum/keys/60s", + "instant": false, + "interval_secs": 2, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 4, + "keys_per_window": 2500 + }, + "lookback_secs": 60.0, + "max_N": 1500000.0, + "max_covered_share": 0.25, + "metric": "data", + "min_N": 1500000.0, + "min_covered_share": 0.25, + "queries_per_instance": 1, + "query_id": "topk4_q06-topk-sum", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 6000000.0, + "covered_min_N": 6000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-07", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-07/topk8_q07-topk-sum/keys/1200s", + "instant": false, + "interval_secs": 60, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 1200.0, + "max_N": 6000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 6000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk8_q07-topk-sum", + "range": "1200s", + "stream": "data/value" + } + ], + "schemas": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ] + } + } + } + ] +} diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/inference_config.yaml new file mode 100644 index 00000000..7832e815 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/inference_config.yaml @@ -0,0 +1,80 @@ +cleanup_policy: + name: circular_buffer +metrics: + data: + - job + - label_0 + - region + - service +queries: +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service) (sum_over_time(data[10m])) + planned_subquery: sum by (job, region, service) (sum_over_time(data[10m])) + query_time_aggregations: + - operator: sum + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service, job) (sum_over_time(data[10m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[10m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + num_aggregates_to_retain: 30 + query: topk by (region) (4, sum_over_time(data[1m])) + planned_subquery: topk by (region) (4, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 4 + num_aggregates_to_retain: 20 + query: topk by (region, service) (8, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (8, sum_over_time(data[20m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region, service, job) (quantile_over_time(0.99, data[100s])) + planned_subquery: quantile_over_time(0.99, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region, service, job) (quantile_over_time(0.95, data[100s])) + planned_subquery: quantile_over_time(0.95, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 76 + query: avg by (region) (quantile_over_time(0.50, data[100s])) + planned_subquery: quantile_over_time(0.5, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + parameter: null diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/plans.json.gz b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-07-pilot/plans.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..ae91c0ab27d3931239ef64f4fdd056e3f82989bb GIT binary patch literal 2496 zcmZY7c{~%0AHZ>GkE}>0S9|1|rE89-tk85YHaRor@E~QbS+4wM9i{^la~4Apo;jv6 z)k1zESBx1Z*B&7~j+7%A%~Q(j_j~brzrL@}f8W>lkFRo^xOnQ(4qwsLAb*d*V3=<( zK2T&T%L3ouum`ysd%rsX@87;C;SypK;(9-m0TaERreIzHX?b{_CqB!ckx<$fi})R# z=C5&l$5vgVv$OeTd#l)@j=-654*U^y-Oa0P)bRTd!Z>-^IIWoul#YD zm&*m*(!f}K*z`!_6{mJ$@+E5ucOtx6=+9YV%`NkDUQ#1_SMX+^eCoti*vKX1$B`}NL+fXlT%yVslE^XG%K$C z>f%e{i3~krzp~uYAz1bWtJtMS{sr$t5$5MU#&WuY+~7OdayWFvk`*T>Au#Tk1Yxi0W8yzk4X?QknH4q1_7JkY?YEER zKV@&rViojuV+JPY7q{V5v+Og+FheD?!n(R}$n>NP|6v?hwSD6C=+vN(GZrhqxNt)z z*U}W@EBReUXM)Jxn1f&{y-X(aZ zsHO5k{8xe-n?dB!zZ^EF*=tvWhuNKlAy*@-t~2adM)dYhd*w7@I&aPip`1O4e5ZM^ z;>z|e!T#QHiKeGkS_k{C1dp*epLHN3wBhmE}nV7)cYKBFW{!!+bD$!LD)4;Odcq&|G}*3p%vT{PeF0155e9J9+&$9&;64E zmz{n`2=LVo%vg+(BSG_UNsMH2`Zk(#0@NuuaWAG_gCq&V`?9B&J*M_=$?!nfturh|HB#&id z{3%(l9C_=kxfa=lphAY%F3qpB+c{bmROk*VXq3vb!MH>f>UY5M7!P3i4_3SXuy83u z7c|^@>LxxyTX52z)(OrR7-a*N0C<5hrRVnFsh~c_-9%fHzbOytu07a&=Ff2!);)@o zOc^;TkW>;v8 z7~gFqobjIN?m}dqGZJ|bdm&XCQBIf^nk3pLWm9$9j|sj}l3*00qA~M{q-*zlv!*3>El&x-8aZCjGVS7=Vt40mE|5UnOco zB!FkuvgCi$IDMn&AM10?Hw)bBL)JnC#cQE@EY{^Dl`LPbdm#-Swv0xpfNlfSuA8kT zN0O?LywSS7={fLRk;plmlURq_kp)S24Zx9#-h}dkX>sTEmsA3 zZ*qH}S|&z!GnO|~k_~x#lno)k*JYvKeN^B15t#unq(UE) zFZ1wm|4`99ZPhmCNMErPfSyLi|9n)>D9{!Xhy;o@&iM%daktK4UK^DbQ2R%lr!^I6 zcKUNYX!ZEo`}G^FFjgJlVj9Qw#56eYbxP*BGwQ3Eze}K-WXPZ&hnQ)vrD@y?BBrsC z3d`LHMBZ$czL=h84LYA^okU9hh5H1ujQFzJTKfQSf}lBUb_{eUT74~sBBp9K8=X!f zhCv={ZkD4EO*TQL#G9Z57VFxR=9hc7);!icWpxPszs1q&Qnggal#LQcvz1VX(3`Xr zB8TtWBzfoAfUe5?!ev5)2tfzl5Zx=207?WvwxCX~rI~yUqNcHtCJS!`O5SL;QExy0 X%2y*15s}r^tsVZ_+k=h8*VREm(P#Do8SigWU`zoi@z! zqr9AEY9`uM2t>%(9ae7sJBlre&gy5#<@sLgmoP?&M3+TYOKR5Nqv+Pnd7SWNVT&xy zdA&wHHj^4lEe_dz%ZbZwEaGfz&Rw~6T16MSgS9I zsQ3$4m4%P4i_WE_r0{jPzjx|l_(oKk@kN#`l)B)}@_Se%c`M!L71mK5S7hmo5-uDsHiOVTj1TrztP6lLha0C$+^e-Cu(q)IbW>c^O3tGOuCV!AKyP{ zi>e#X9vLvHp);2*IY=ZQy8hL8RCsZ{au)iKUn#xG5q4rja5 zS;i^n?_?koqn0L3$#jpydRrxa$puCW;gJ?#9@oU!{4z(n%IT%t`xCgt(?C&$VQ(v` z(0t6fL&zoBJMmokDsH%&LUyl9SuW`K=ZWlBbZ`6Xi4J^4P%e+%>o*Muh#lePtu4rWA^GJDQ9pt(uG)wD#VLaFCy_F}7H9EiapmFUp_rgvJ|+gRP?9 zZUkP4y_X+*ckALqr8yacOBI%t3KNO^!5)U>Yf&*HoW4-t%pd6-^!nRrUUQumPk$!SK7I_&zYxc!WiR0^eJ3I7;21c}#_i3W;sYK$jnpvf@K>^0lMMTZ|T>H2I@*fYUl?7)%t;LEi`Dv;~iA^2kvOMKvnS(_!`$%0P%~+ z8bx~}P&nxSz(3(!2rjSO)j(L#9-eWZj|IWh`-5TXN}A*l&#)bbsJb~pFtEH8R|9$; zvcbW6jW!<_nSt*b=28ZfbBt<#OTSiW9Gi1+CcIRZ2_HY}t=?p_qdWv}b8-V7$BhO+ z?EWA)2msM}K?qm{0Vr8-UdwuxtdgMuaI<^v?R6NTqL3i1xE5r=o_WB@>-- zm@67})E00?F#hgRA)ve<@NK-6;84-P^Jbf^ z_Vp1uboUAUe;>xccCiQOlk`c|!v}W5?o^`HYd=(0-w0M#x7Mr=X$sqcr=r?|RKOPz zkN`{?R1&;D00YxN%=||H@Bw^sB4^=D#2)F`t;y}eeujyVR}j*?X}5z(Ucrbn5j1W; zfR{a36`>FC(k1t&Lv}T&(y%mavJ=;C*qtzD6=Vz&;Xel9NuZt;RTSHnVO1`ofPe<* z0qVuj)8IcEFva>;O@P4v0B_)L;B-4I5WE-d)s+y`{dF`51Y)r`K+;9?L2jjNpnm~j C{ZDHE literal 0 HcmV?d00001 diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/streaming_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/streaming_config.yaml new file mode 100644 index 00000000..bb94015b --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-08-pilot/streaming_config.yaml @@ -0,0 +1,89 @@ +aggregations: +- aggregationId: 1 + aggregationSubType: '' + aggregationType: DDSketch + labels: + aggregated: [] + grouping: + - job + - label_0 + - region + - service + rollup: [] + metric: data + parameters: + alpha: 0.1 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 20000 + windowType: sliding +- aggregationId: 2 + aggregationSubType: sum + aggregationType: MultipleSum + labels: + aggregated: + - job + - region + - service + grouping: [] + rollup: [] + metric: data + parameters: {} + slideIntervalMs: 10000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 10000 + windowType: tumbling +- aggregationId: 3 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + - service + grouping: + - region + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 120 + width: 1024 + slideIntervalMs: 1000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 2000 + windowType: sliding +- aggregationId: 4 + aggregationSubType: sum + aggregationType: CountMinSketchWithHeap + labels: + aggregated: + - job + - label_0 + - service + grouping: + - region + rollup: [] + metric: data + parameters: + depth: 3 + heapsize: 160 + width: 4096 + slideIntervalMs: 30000 + spatialFilter: '' + table_name: null + value_column: null + windowSizeMs: 30000 + windowType: tumbling +metrics: + data: + - job + - label_0 + - region + - service diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/eval_table.json b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/eval_table.json new file mode 100644 index 00000000..68f526ec --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/eval_table.json @@ -0,0 +1,398 @@ +{ + "inputs": { + "workload-09.json": "b5050e8d5ef16a3d4c7a14e6396e40b0e8bcb40c0eb4d56b1ca4959d1b8a40f7" + }, + "plan": "ProjectASAP/ASAPQuery#879", + "schema_version": 1, + "sketch_bench_revision": "f885d7e9a99dd435683a7dcd66516a36b3ac02ab", + "workloads": [ + { + "dataset": "random/seed=862/workload-09", + "e2e": { + "metrics": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ], + "samples_per_sec_per_series": 10, + "type": "gauge", + "values": { + "dist": { + "pareto": 2.0 + }, + "value": { + "keys": 10000, + "zipf": 1.1 + } + } + } + }, + "queries": [ + { + "interval_secs": 2, + "promql": "sum by (region, service, job) (sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-09/q01-sum-fine/keys/60s" + ] + }, + { + "interval_secs": 2, + "promql": "sum by (region, service) (sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-09/q02-sum-coarse/keys/60s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.75, data[100s]))", + "rqes": [ + "random/seed=862/workload-09/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service, job) (quantile_over_time(0.95, data[100s]))", + "rqes": [ + "random/seed=862/workload-09/q04-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "avg by (region, service) (quantile_over_time(0.75, data[100s]))", + "rqes": [ + "random/seed=862/workload-09/q03-quantile/values/100s" + ] + }, + { + "interval_secs": 1, + "promql": "topk by (region, service) (8, sum_over_time(data[1m]))", + "rqes": [ + "random/seed=862/workload-09/topk8_q06-topk-sum/keys/60s" + ] + }, + { + "interval_secs": 30, + "promql": "topk by (region, service) (8, sum_over_time(data[20m]))", + "rqes": [ + "random/seed=862/workload-09/topk8_q07-topk-sum/keys/1200s" + ] + } + ] + }, + "rqes": [ + { + "assumptions": [], + "capability": "sum", + "covered_groups": 200, + "covered_max_N": 30000.0, + "covered_min_N": 30000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service", + "job" + ], + "id": "random/seed=862/workload-09/q01-sum-fine/keys/60s", + "instant": false, + "interval_secs": 2, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 200, + "keys_per_window": null + }, + "lookback_secs": 60.0, + "max_N": 30000.0, + "max_covered_share": 0.005, + "metric": "data", + "min_N": 30000.0, + "min_covered_share": 0.005, + "queries_per_instance": 1, + "query_id": "q01-sum-fine", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "sum", + "covered_groups": 20, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "exact-sum", + "grid_K": null, + "grid_param": null, + "sketch": "exact-sum", + "target": 0.0 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-09/q02-sum-coarse/keys/60s", + "instant": false, + "interval_secs": 2, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": null + }, + "lookback_secs": 60.0, + "max_N": 300000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "q02-sum-coarse", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-09/q03-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q03-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [], + "capability": "quantile", + "covered_groups": 10000, + "covered_max_N": 1000.0, + "covered_min_N": 1000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "kll", + "grid_K": null, + "grid_param": 2.0, + "sketch": "kll-percall", + "target": 0.01 + }, + { + "family": "dd", + "grid_K": null, + "grid_param": 2.0, + "sketch": "dd", + "target": 0.01 + } + ], + "grouping": [ + "region", + "service", + "job", + "label_0" + ], + "id": "random/seed=862/workload-09/q04-quantile/values/100s", + "instant": false, + "interval_secs": 1, + "kind": "values", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 10000, + "keys_per_window": null + }, + "lookback_secs": 100.0, + "max_N": 1000.0, + "max_covered_share": 0.0001, + "metric": "data", + "min_N": 1000.0, + "min_covered_share": 0.0001, + "queries_per_instance": 1, + "query_id": "q04-quantile", + "range": "100s", + "stream": "data/dist" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 300000.0, + "covered_min_N": 300000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-09/topk8_q06-topk-sum/keys/60s", + "instant": false, + "interval_secs": 1, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 60.0, + "max_N": 300000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 300000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk8_q06-topk-sum", + "range": "60s", + "stream": "data/value" + }, + { + "assumptions": [ + "500 keys per heap read at the curves' 1000" + ], + "capability": "topk", + "covered_groups": 20, + "covered_max_N": 6000000.0, + "covered_min_N": 6000000.0, + "covers_share": null, + "dataset": "random/seed=862/workload-09", + "families": [ + { + "family": "topk", + "grid_K": 1000, + "grid_param": 1.1, + "sketch": "cms-heap-topk-fastpath-vector2d", + "target": 0.95 + } + ], + "grouping": [ + "region", + "service" + ], + "id": "random/seed=862/workload-09/topk8_q07-topk-sum/keys/1200s", + "instant": false, + "interval_secs": 30, + "kind": "keys", + "label_set": { + "arrival_rate_per_sec": 100000, + "groups": 20, + "keys_per_window": 1000 + }, + "lookback_secs": 1200.0, + "max_N": 6000000.0, + "max_covered_share": 0.05, + "metric": "data", + "min_N": 6000000.0, + "min_covered_share": 0.05, + "queries_per_instance": 1, + "query_id": "topk8_q07-topk-sum", + "range": "1200s", + "stream": "data/value" + } + ], + "schemas": { + "data": { + "labels": [ + { + "cardinality": 4, + "name": "region" + }, + { + "cardinality": 5, + "child_of": "region", + "name": "service" + }, + { + "cardinality": 10, + "child_of": "service", + "name": "job" + }, + { + "cardinality": 50, + "child_of": "job", + "name": "label_0" + } + ] + } + } + } + ] +} diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/inference_config.yaml b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/inference_config.yaml new file mode 100644 index 00000000..45c15960 --- /dev/null +++ b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/inference_config.yaml @@ -0,0 +1,81 @@ +cleanup_policy: + name: circular_buffer +metrics: + data: + - job + - label_0 + - region + - service +queries: +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service) (sum_over_time(data[1m])) + planned_subquery: sum by (job, region, service) (sum_over_time(data[1m])) + query_time_aggregations: + - operator: sum + grouping: + mode: by + labels: + - region + - service + parameter: null +- aggregations: + - aggregation_id: 2 + num_aggregates_to_retain: 30 + query: sum by (region, service, job) (sum_over_time(data[1m])) + planned_subquery: sum by (region, service, job) (sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 3 + num_aggregates_to_retain: 58 + query: topk by (region, service) (8, sum_over_time(data[1m])) + planned_subquery: topk by (region, service) (8, sum_over_time(data[1m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 4 + num_aggregates_to_retain: 40 + query: topk by (region, service) (8, sum_over_time(data[20m])) + planned_subquery: topk by (region, service) (8, sum_over_time(data[20m])) + query_time_aggregations: [] +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region, service, job) (quantile_over_time(0.75, data[100s])) + planned_subquery: quantile_over_time(0.75, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region, service, job) (quantile_over_time(0.95, data[100s])) + planned_subquery: quantile_over_time(0.95, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + - job + parameter: null +- aggregations: + - aggregation_id: 1 + num_aggregates_to_retain: 81 + query: avg by (region, service) (quantile_over_time(0.75, data[100s])) + planned_subquery: quantile_over_time(0.75, data[1m40s]) + query_time_aggregations: + - operator: avg + grouping: + mode: by + labels: + - region + - service + parameter: null diff --git a/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/plans.json.gz b/asap-tools/experiments/datasets/fake_metric/random_workloads/seed-862/workload-09-pilot/plans.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..1a3e25427ddd21e3c013d23954952632bf5d6e50 GIT binary patch literal 2309 zcmY+?dpHw{8wYT=3^}Icei?F*+{u`XXmV%HV;z-ADc6ip%oxp4Y*JCkZ5JUEVk8Z@ z%Uz0cSuQcxkXsva>UYxf^L+kzpXdF)&-bqvgy-W+J<;pSwHxT~5fH5D8;lCzSjcj7 z9JZ3M+_g!eE(XM~vR8`H&*#={BFfKF)pX-+ogWx};8!nXf4bQcBWCV=LEwoYlk3>Sv16A`n6AC9Vc=GQSgN=k;cSB3uvqVEj zhMH3w%aB4>rwY>YMzwewn+rGnmU^&^?_W2Tu*mhOc{jnU%?rM8j0+;Q1i5)vrQb(q zPS$+`5xQ~)^;iqfS}xnn18Xo+2qv_CED_hNkH*dmR!P1%tAM5aKl7yxT6Lvva=n2B%z-*%E5Ts;n zem(BhK$hLzj8IGdqeWewBMm;Ji9#w^JM9TYGQu0Tf#gef)p(dF{kh8nK)Ix&q2<*~ zH_}KZtN(Qv_x@6#XrY~#j^_NO+Ncs%U{!+n)ODv+s&861efRABL8@<-4Z0jRf9-L< zNSBL|Rw3FcX;p1e$K5_ZXf~D7dd2mEwoijxE>#-r2taMrt_L)EJaRpjl6ve8QExET zEvu>A!4#Wf@Yd%A3^~=M2{L_VdUWYOwc~ma#4zzw z?4y-D*@iK@D%_e{;+!lc%8&|t3m+V=>6xEWbiWJio|JJ#6xwgIt^0fII@VrvRb`B4 zERIX}5lGbK3Utx(j^#J!_@%_Um%FIXTF@Fl&HA0wA=+9Zenms1`=ZJ-_pT^>O%#TV zoTg~Z2axag5XuI4RR~eqQXj8*E16Mp4kzZKWYfYLn#N=d0o^gdW0^HmneWT!kS{g& zC_-13HJcnu?{!O|w!K^vRGcm{BO{ig_oS#3 zv#m}2yfpIiw3?8xbmKsMxFlVt&G;w%3UA-OcefIT@d0HmVmQ_(|6T&<)puBslZ9K4R9|Jm$D6G9qa zUTm~Ak}&xx<+?Un8(r<*5tMzd`^CWZIiFgFR^9iD#mwW`9TuMiDsCghF{i0`ggCaO zHm4!j7&0Mga`7-4*vY;6`lL3nvp;lt95pl>-N#Acwgd={khohu(Qei>HBRyeJ^p|0 zx&8DvMpAvZg~Z4}d#!de{Tgp{-x^sUL`znI9c_IF`lIcCrH+H?fWF^GPOY6*nW{oKL}fn`8@bx#l*dF0kiMBgTP2_`#(JZZiWlYB4oS66g)x5baMJ#^dx zZlRy0_R-%A^Wog|Qbw z9{?LMkv|5LbD_L(>tmvca~R55w#};rGQ1XtYBRM-So|W@|L3Xm1=`nEZ#OG{Hb( zooH|;mWxM|#8D3|1uk%Jy@qZzKvm85Tm%XT3-s2eV4R}&t6oRd1x9=Oj&t+@D2k^+ z1gJ!$wt)FF34VS)q&XK?R5WM|@QpKSgEy))de4}gy1Y8E<`|pEN!llL&f3h|j8@Sb zJrfH*Oct?JAvj2gl5P-Ud3m%*oSdewfy><69HtT6rrtje{}Tw55|-*^9Et3W-miLH zU;d;#`&^hAt)YOwPkGx{W2v)D4NTjGZX^T4Wp9X7CQ8M8!}eW{_-U$z=#*Y%$WzSmH+A zh%AX48A43ijc#_ry=F9-!MswPa}V!(KIiv&j0FO7wBPx2b8cL_ghHS2 zM+c&~J`+6ABLl}QIlPk<)WRX!1bB%-q%QU_N)W!MQuveYQiZc$RVrk1qQ7J>K_cZ^ zf60d|%81E8_$2SRhCh(o*qVD@uKvd5q!Ft)OsfKGI$SW&cG=aFpmRlkLrpJ)RoD6S zh*jV%tF@3}a!pjde%XCDPWiFy$;S2TF&YGB^z!Bw6Uzn0P)$p-Aw<8Li>uei(G zllxo6ACUy@hlG~$*}v+JhnW}ztWf2Lyb`qC14J5onZ`zOTP`%hdj%bU5}5P4+N^K6 z_Oxp0uoo0|ucM&R+3{D!bZYI=+Uz5>Y|tn2s$!Z z16)dqDS!6mF|07H9Ljd>VqL|DZat6a8Bh`@@XPS}d^myr&-I?T^0It{{m56v*Z~_# zI;tMk(r{0#GGbQE%I_%1NV%Pg{j_B~p>G!zX{;{)tgp_fNvWNVX~nA`1rk+Gc78ar zBv?R{Zj&JUT{LXVHQ9f?b`HOkOVAIxpy!i}|uIg?*Xd9s|kFQ+s8%-LcQ zqo@p2Px<^6&Z$jVjICav5NohiV)pzx~r(e279(f=L2sQ}1vJDs4HKAEnaU4;B}!F36s& zY+4i+C9U;0;G;3EWkLvn{-lkKDNw7t7o&=PcRwP1YTwlQMPu>awEGLH^WYjWyQ&N`TOPT;bJS!st0cVCf6kkfp%>cU4) zq6-#~1fb-CZUQ8s!rSA{n-$a8G244B6u@oiVv?=5xw-W&9bj1eSPB;2m20o6<1XUN zI;TFI4jZmPx6c*Wm(AB8?5z^`llUokVKLASoZDmKk39?FTNOv zW1z_a7-;?WH}c&K9y88vC>QqxEtuy3q)n}bK=C_S%>(Y;z;hO5eAhf@FOQgqhh9Ru zwO>N6=>8OE)46PXVK7yLCsf9^HC+S3&vSMs>mGMs=k5lOsRf%8ZTG6QcvHofxsuE> zN_b%qb!0x~EX{A8#LLr7a>fpjwK@&KHIB-v)|n$6=G+6hQlzK9_=2|KUgno%zs%pp z*09PdsR)-thm|}IgiWwSZJDrXZ`Qx-0xvX@QG!*zh^pw^#htCAPmv zr0>TomO)_klJubTL)P3lGH`p`p3>#TiC0s)`ITx?<~@8!A*RL644k1@mM1p7PhX;d zF``mRG9#E108%i8?^-%?oD|eVUnGW4$p-~%TFZ+%8{Ea?Pg(j+L3g37FbC1H4sb77 zhyHNt51PM|>9pCvcGJRm;|zs;&@-TP0Awd)2drfrc8kq$$g|pg`R$C_>JR=5J$CIg z)F$w!k}NzeVpC0jF7uTF3j*PRn&HyF$50x&v4`F&^e_})vqxttVnWKX|B|dDJi_S* z%}VkY+Tt_~h<~NPE%)!$4buN($Nyd3oipL(2>14J?2n-Spjky`(pC;kDB|BK@X9Ij w*u>(BAUiQMgC4ip?aV4t6AH1}r4#H%jAZ}C;o{=raQ1UO$a5!rTHeR?U& Date: Wed, 14 Oct 2026 22:51:04 -0400 Subject: [PATCH 24/25] fix(asap-tools): pin the pilot's ClickHouse to 23.8 clickhouse-server 26.6 and later die with an illegal instruction on CloudLab's Xeon E5-2450 nodes (no AVX2), so both ClickHouse arms failed to start. The ClickHouse semantics tests pass on 23.8 too. Co-Authored-By: Claude Opus 5.5 --- .../datasets/fake_metric/random_workload_artifacts.py | 4 ++++ .../experiments/tests/test_random_workload_artifacts.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py index a18dbdd1..1ec9b934 100644 --- a/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py +++ b/asap-tools/experiments/datasets/fake_metric/random_workload_artifacts.py @@ -31,6 +31,9 @@ # Relative to EXPERIMENTS_DIR, where the runners read configs and SQL. CONFIG_DIR = "config/experiment_type/random_workload" VICTORIAMETRICS_URL = "http://localhost:8428" +# 26.6 and later need AVX2, which CloudLab's Xeon E5-2450 nodes lack; the +# ClickHouse SQL's semantics tests also pass on 23.8. +CLICKHOUSE_IMAGE_TAG = "23.8" PROMQL_METRICS = ("data", "data_total") SQL_EVENTS_TABLE = { "name": "events", @@ -215,6 +218,7 @@ def pilot_configs(workload, pilot_dir): "name": "custom", "init_sql_file": str(out_dir / init), "paced_feeder": feeder, + "clickhouse_image_tag": CLICKHOUSE_IMAGE_TAG, }, "query_groups": groups, "data_ingestion_interval_ms": workload["data_facts"]["scrape_interval_ms"], diff --git a/asap-tools/experiments/tests/test_random_workload_artifacts.py b/asap-tools/experiments/tests/test_random_workload_artifacts.py index 2ca3fc54..35ef2be6 100644 --- a/asap-tools/experiments/tests/test_random_workload_artifacts.py +++ b/asap-tools/experiments/tests/test_random_workload_artifacts.py @@ -140,6 +140,8 @@ def test_every_arm_feeds_the_same_data_and_schedule(self): self.assertEqual(vm["monitoring"]["tool"], "victoriametrics") self.assertEqual(raw["experiment"][0]["mode"], sbw.BASELINE) self.assertEqual(mv["experiment"][0]["mode"], sbw.BASELINE_MV) + for config in (raw, mv): + self.assertEqual(config["dataset"]["clickhouse_image_tag"], "23.8") self.assertIn( "prebuilt_output_dir", yaml.safe_load(files["e2e.yaml"])["controller"] ) From a1f9d66cef7906aa684b6edd6b0aebc2418e4c27 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 15 Oct 2026 00:02:47 -0400 Subject: [PATCH 25/25] feat(asap-tools): compare a workload's arms across runs compare_arms.py reads each arm's mode directory and prints per-query latency and the share within the repeat interval, agreement with a reference arm (mean relative error, or precision@k for top-k), and each arm's total CPU-seconds and peak memory from remote_monitor. Co-Authored-By: Claude Opus 5.5 --- .../multi_experiment/compare_arms.py | 191 ++++++++++++++++++ .../experiments/tests/test_compare_arms.py | 40 ++++ 2 files changed, 231 insertions(+) create mode 100644 asap-tools/experiments/post_experiment/multi_experiment/compare_arms.py create mode 100644 asap-tools/experiments/tests/test_compare_arms.py diff --git a/asap-tools/experiments/post_experiment/multi_experiment/compare_arms.py b/asap-tools/experiments/post_experiment/multi_experiment/compare_arms.py new file mode 100644 index 00000000..dc7bf986 --- /dev/null +++ b/asap-tools/experiments/post_experiment/multi_experiment/compare_arms.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +"""Compare one workload's arms, each a mode of its own experiment run. + +For every query: latency (p50/p95/p99) and the share answered within its +repeat interval; each arm's agreement with a reference arm (mean relative +error, or precision@k for top-k); and per arm the total CPU-seconds and peak +memory from remote_monitor's samples. Arms must have run the same queries in +the same order on the same data (same feeder seed), so (query group, query, +repetition) names the same window in every arm. + +Usage: + python3 compare_arms.py --reference prometheus \\ + --arm asapquery=experiment_outputs/w01_asap/sketchdb \\ + --arm prometheus=experiment_outputs/w01_prom/baseline \\ + --arm clickhouse_mv=experiment_outputs/w01_ch_mv/baseline_mv +""" + +import argparse +import gzip +import json +import statistics +from collections import defaultdict +from pathlib import Path + +import yaml + + +def read_jsonl(path): + with gzip.open(path, "rt") as f: + return [json.loads(line) for line in f if line.strip()] + + +def sql_labels(sql): + """The label columns a ClickHouse statement selects before its value, + after any leading `-- description` line.""" + lines = sql.splitlines() + body = "\n".join(lines[1:]) if lines and lines[0].startswith("--") else sql + cols = [] + for token in body[len("SELECT ") :].split(", "): + if "(" in token: + break + cols.append(token.strip()) + return cols + + +def query_name(query): + """PromQL as is; ClickHouse SQL by its `-- ` description line.""" + first = query.splitlines()[0] + return first[2:].strip() if first.startswith("--") else query + + +class Arm: + """One experiment mode's latencies, results, intervals and resources.""" + + def __init__(self, mode_dir): + mode_dir = Path(mode_dir) + out = mode_dir / "prometheus_client_output" + self.latencies = defaultdict(list) # (group, query) -> [seconds] + for r in read_jsonl(out / "query_latencies.jsonl.gz"): + self.latencies[(r["query_group_idx"], r["query_idx"])].append(r["latency"]) + self.results = defaultdict(dict) # (group, query, rep) -> {labels: value} + self.names = {} + for r in read_jsonl(out / "query_results.jsonl.gz"): + key = (r["query_group_idx"], r["query_idx"], r["repetition_idx"]) + self.names[key[:2]] = query_name(r["query"]) + window = self.results[key] + if "raw_text_result" in r: + cols = sql_labels(r["query"]) + for line in (r["raw_text_result"] or "").strip().splitlines(): + *labels, value = line.split("\t") + window[tuple(sorted(zip(cols, labels)))] = float(value) + elif r.get("result_labels") is not None: + labels = json.loads(r["result_labels"]) + labels.pop("__name__", None) + window[tuple(sorted(labels.items()))] = float(r["result_value"]) + client = mode_dir.parent / "controller_client_configs" / f"{mode_dir.name}.yaml" + groups = yaml.safe_load(client.read_text())["query_groups"] + self.interval_secs = [g["repetition_delay_ms"] / 1000 for g in groups] + self.monitor = mode_dir / "remote_monitor_output" / "monitor_output.json" + hydra = yaml.safe_load((mode_dir.parent / "hydra_config.yaml").read_text()) + self.monitor_interval_secs = float(hydra["flow"]["monitor_interval_seconds"]) + + def resources(self): + """(total CPU-seconds, peak memory bytes), summed over monitored + processes at each sample.""" + processes = json.loads(self.monitor.read_text()).values() + n = max(len(p["cpu_percent"]) for p in processes) + cpu, mem = [0.0] * n, [0.0] * n + for p in processes: + for t, c in enumerate(p["cpu_percent"]): + cpu[t] += c + for t, m in enumerate(p["memory_info"]): + mem[t] += m + return sum(cpu) / 100 * self.monitor_interval_secs, max(mem) + + +def percentile(xs, p): + xs = sorted(xs) + return xs[min(len(xs) - 1, int(p / 100 * len(xs)))] + + +def agreement(got, want, topk): + """`got`'s window against reference `want`: the share of `want`'s series + `got` returns (top-k), else the mean relative error over shared series + and the number of `want`'s series `got` lacks.""" + if topk: + return len(set(got) & set(want)) / len(want), 0 + errors = [abs(got[k] - v) / abs(v) for k, v in want.items() if k in got and v] + return (statistics.mean(errors) if errors else None), len(set(want) - set(got)) + + +def report(arms, reference): + names = arms[reference].names + print("== Latency (s): p50 / p95 / p99, share within the repeat interval") + for gq, name in sorted(names.items()): + interval = arms[reference].interval_secs[gq[0]] + print(f"\n[{gq[0]}.{gq[1]}] every {interval:g}s: {name}") + for arm_name, arm in arms.items(): + xs = arm.latencies.get(gq) + if not xs: + continue + within = sum(x <= interval for x in xs) / len(xs) + print( + f" {arm_name:16s} n={len(xs):5d} {percentile(xs, 50):8.3f} " + f"{percentile(xs, 95):8.3f} {percentile(xs, 99):8.3f} {within:6.1%}" + ) + + print(f"\n== Agreement with {reference}") + ref = arms[reference].results + for gq, name in sorted(names.items()): + topk = name.startswith("topk") + print(f"\n[{gq[0]}.{gq[1]}] {name}") + for arm_name, arm in arms.items(): + if arm_name == reference: + continue + values, missing, empty = [], 0, 0 + for key, want in ref.items(): + if key[:2] != gq or key not in arm.results: + continue + if not want: + empty += 1 + continue + value, lacking = agreement(arm.results[key], want, topk) + missing += lacking + if value is not None: + values.append(value) + if not values: + print(f" {arm_name:16s} no comparable windows") + continue + worst = min(values) if topk else max(values) + what = "precision@k" if topk else "mean rel err" + print( + f" {arm_name:16s} {what} {statistics.mean(values):.3g} " + f"(worst {worst:.3g}) over {len(values)} windows; " + f"missing series {missing}, empty reference windows {empty}" + ) + + print("\n== Resources (whole monitored run)") + for arm_name, arm in arms.items(): + cpu_secs, peak = arm.resources() + print( + f" {arm_name:16s} CPU {cpu_secs:9.0f} s peak memory {peak / 2**30:5.2f} GiB" + ) + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "--arm", + action="append", + required=True, + metavar="NAME=MODE_DIR", + help="an arm: its name and its experiment's mode directory", + ) + parser.add_argument( + "--reference", required=True, help="the arm others are scored against" + ) + args = parser.parse_args() + arms = {} + for spec in args.arm: + name, _, mode_dir = spec.partition("=") + arms[name] = Arm(mode_dir) + if args.reference not in arms: + parser.error(f"--reference {args.reference!r} is not an --arm") + report(arms, args.reference) + + +if __name__ == "__main__": + main() diff --git a/asap-tools/experiments/tests/test_compare_arms.py b/asap-tools/experiments/tests/test_compare_arms.py new file mode 100644 index 00000000..99c5ac33 --- /dev/null +++ b/asap-tools/experiments/tests/test_compare_arms.py @@ -0,0 +1,40 @@ +"""Tests for post_experiment/multi_experiment/compare_arms.py.""" + +import os +import sys +import unittest + +sys.path.insert( + 0, + os.path.join( + os.path.dirname(__file__), "..", "post_experiment", "multi_experiment" + ), +) + +import compare_arms # noqa: E402 + + +class CompareArmsTest(unittest.TestCase): + def test_sql_labels_skip_the_description_and_stop_at_the_value(self): + sql = ( + "-- topk by (region) (4, sum_over_time(data[1m]))\n" + "SELECT region, label_0, sum(value) AS value FROM data GROUP BY region, label_0" + ) + self.assertEqual(compare_arms.sql_labels(sql), ["region", "label_0"]) + self.assertEqual( + compare_arms.query_name(sql), + "topk by (region) (4, sum_over_time(data[1m]))", + ) + + def test_agreement_scores_values_and_topk_sets(self): + a, b = (("region", "0"),), (("region", "1"),) + self.assertEqual( + compare_arms.agreement({a: 11.0}, {a: 10.0, b: 5.0}, False), (0.1, 1) + ) + self.assertEqual( + compare_arms.agreement({a: 1.0}, {a: 9.0, b: 8.0}, True), (0.5, 0) + ) + + +if __name__ == "__main__": + unittest.main()