Repository navigation
Tracker: run #777 eval plans end to end from saved plans #824
Copy link
Copy link
Closed
Description
Goal
Take ASAP's saved plans from the #777 evaluation (sketch-bench autosketch_vs_asap, results in sketch-bench#203), convert them to StreamingConfig / InferenceConfig without a ControllerConfig or a re-solve, and run them with asap-tools/experiments/experiment_run_e2e.py. This is for the paper experiments, so it sits beside --planner milp, not inside it.
sketch-bench side: ProjectASAP/sketch-bench#204 (plan file, PromQL and label schema in the workload table).
TODO
- B1. Saved plan → deployments (feat(planner): asap-planner --planner saved writes a sketch-bench eval plan without re-solving #828, merged)
- As built: passes
(deployments, Raqe → deployment)todeployments_to_planner_output, whichplan_to_planner_outputnow wraps, instead of aMilpSolution, whosePlanCosta saved plan can't fill. - Reuse
--planner milp's path (asap-planner-rs/src/main.rs,run_milp):ControllerConfig→build_milp_workload(PromQL → RQEs) →plan_to_planner_output. Only the solve is replaced: load the saved plan instead of callingplan_milp. - Build a
MilpSolutionfromplans/<table>.plans.json.gz: one deployment per distinctchosen[].deployment(sketch, params, window, slide; capability, metric and grouping from the table's RQE), and each ASAPQuery RQE pointed at its deployment. - The link between ASAPQuery's RQEs and sketch-bench's RQE ids is the table's
e2e.queries({promql, interval_secs, rqes}, sketch-bench#204 P2). - The converter is unchanged, with the same refusals (roll-ups, unmapped variants such as Hydra, two deployments for one query).
- (Was: split the converter to work without a
ControllerConfig. Not needed: the table gives us one.)
- As built: passes
- B2.
--planner savedmode (feat(planner): asap-planner --planner saved writes a sketch-bench eval plan without re-solving #828, merged)- As built:
--sla-ms Ninstead of--kind(one SLA plan per SLA; omitted = cheapest). The same-PromQL-at-two-intervals case is left to the existing two-deployments refusal, which fires only when the deployments actually differ. asap-planner --planner saved --plan FILE --workload-table FILE --method asap --weights cpu --kind cheapest --output-dir DIRwritesstreaming_config.yamlandinference_config.yaml.- Builds the
ControllerConfigfrom the table'se2eblock:queriesgrouped byinterval_secs→query_groups;metricslabel names →metrics. - Same PromQL at two intervals reading different RQEs (47 such strings in the r = 8 table) can't be keyed by query string in the inference config: refuse it. The base classic table has none.
- As built:
- B3. e2e with prebuilt configs (feat(planner): asap-planner --planner saved writes a sketch-bench eval plan without re-solving #828, merged:
controller.prebuilt_output_dir; ClickHouse runs in feat(asap-tools): run ClickHouse E2E with frozen plans #860)experiment_run_e2e.pyalways runs the planner (controller_service.start). Add a flag that skips it and syncs a givencontroller_outputdir to the nodes.
- B4. Synthetic workload experiment config (fix(asap-tools): send paced feeder ticks concurrently, ordered per series, in (t, t+1s] #840, feat(asap-tools): generate the paced feeder's data from a workload table #842, feat(asap-tools): generate records metrics in the paced feeder #843, feat(asap-tools): run sketch-bench workload tables end to end with the paced feeder #841, merged)
- As built: the paced feeder replaces the fake exporter. fix(asap-tools): send paced feeder ticks concurrently, ordered per series, in (t, t+1s] #840 → feat(asap-tools): generate the paced feeder's data from a workload table #842 → feat(asap-tools): generate records metrics in the paced feeder #843 (feeder data from the table) and feat(asap-tools): run sketch-bench workload tables end to end with the paced feeder #841 (runner and aligned query client);
sketch_bench_e2e/sketch_bench_e2e_configs.pywrites the experiment config from the table'se2eblock. - Fake exporter: gauge
dataand counterdata_total(decided in sketch-bench#204), each with labelsjobandlabel_0, 1e4 series, 200 samples/s per series (2e6 samples/s per metric), Zipf 1.1 keys, Pareto a = 2 values. label_0determinesjob(each of the 1e4label_0values belongs to one of 10 jobs). The exporter's--num-values-per-labelmakes a cross product (1e5 series), so it needs a way to derivejobfromlabel_0, using the mapping in the workload table's schema (sketch-bench#204 P2).- Check the Rust exporter (
--dataset,--metric-type) covers the distributions. - Query client: the PromQL from the workload table's
queries, each at its RQEs' repeat intervalT(1 s forsum by (job) (data)andquantile by (job), 60 s for the rest).
- As built: the paced feeder replaces the fake exporter. fix(asap-tools): send paced feeder ticks concurrently, ordered per series, in (t, t+1s] #840 → feat(asap-tools): generate the paced feeder's data from a workload table #842 → feat(asap-tools): generate records metrics in the paced feeder #843 (feeder data from the table) and feat(asap-tools): run sketch-bench workload tables end to end with the paced feeder #841 (runner and aligned query client);
- B6. Engine support for 12 classic queries (feat(planner): serve the #777 eval's sum-of-rate and nested topk queries #827, closed)
- As resolved:
topk(sum by (l) (sum_over_time))collapses into one CMS heap (feat(planner): collapse topk(sum by (l) (sum_over_time)) into one CMS heap #849, merged). The two rate templates (7 and 9) are dropped from the eval (sketch-bench#210).--planner savedconverts the full 46-query classic table at 10 samples/s (sketch-bench#212) for all 12 ASAP plans. sum by (job) (rate(...))andtopk(32, sum by (label_0) (...))overrateandsum_over_time(12 of 54 classic queries).--planner savedrefuses the classic tables until they are served.
- As resolved:
-
B5. Dependency pinNot needed.Bump therqe-optimizerpin once sketch-bench P1 lands, if B1 reads its serialized types.- sketch-bench#203 writes the plans as hand-written JSON (
plans/<table>.plans.json.gz), not serialized rqe-optimizer types, so B1 parses that JSON and needs no new rqe-optimizer types.
Order
sketch-bench P1 plan file (done, #203) ──┐
sketch-bench P2 e2e block ───────────────┼─► B1 saved plan → MilpSolution ─► B2 --planner saved ─┐
│ ├─► e2e run (classic r=1 m=1)
B3 e2e skip-planner ─────────────────────┴──────────────────────────────────────────────────────┤
B4 exporter + query config ◄── P2 ───────────────────────────────────────────────────────────────┤
B6 engine: sum-of-rate, nested topk (#827) ─────────────────────────────────────────────────────┘
Not in scope
- Roll-ups and Hydra in the engine (fix(planner): refuse roll-up plans in milp_output #814 refuses roll-ups). Multi-grouping waits on these.
- Switching
--planner milpfrommilp::minimizetominimize_usage_cost(sketch-bench#188). Not needed here, since the eval's plan is read, not re-solved. - Arrival-rate mismatch (eval 2e6 samples/s vs. scrape-based e2e): tracked as a decision in the sketch-bench issue.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
milindsrivastava1997 commentedon Oct 15, 2026
Done. All items are complete (B5 not needed), and the classic r=1 m=1 run works end to end from the saved plans.
Smoke runs on CloudLab (classic table, cheapest cpu-weighted ASAP plan via
--planner saved,controller.prebuilt_output_dir, paced feeder at 1 sample/s per series, compared with a Prometheus baseline over the same data):sum by (job) (data),sum_over_time,sum by (job) (sum_over_time)andratematch Prometheus exactly. The exception is ranges whose start falls inside the data: 15m sums differ by ~0.1–0.3% per job, consistent with Prometheus' closed[E-W, E]vs. ASAPQuery's left-open(E-W, E].topk(32, sum_over_time)has median <1% (max ~10%).quantile_over_timeis served from a sliding 5m/1m DDSketch. It returns results once the full range is covered: 15m with a 20 min starting delay, median ~5% error (max up to 31% at p99). The 1h/6h/24h ranges need runs at least that long.Follow-ups, not tracked here:
experiment_run_e2e.pyteardown leavesblackbox_exporterrunning on the main node.