Repository navigation
feat(asap-tools): generate records metrics in the paced feeder - #843
Merged
Merged
Conversation
…n (t, t+1s] Remote write sent one sub-second slot at a time, so at most one request was in flight per slot. At 200 samples/s per series ASAPQuery's ingest took about 45 ms per 1e4-row request and the feeder reached only 0.2-0.27M rows/s. Each tick now goes out concurrently. Its samples sit in (t, t+1s], the same left-open interval as ASAPQuery's one-second windows, so the reordering within a tick never crosses a window boundary and stays within the allowed lateness. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
`--workload-table FILE` reads `workloads[0].e2e.metrics` of a sketch-bench workload table and sends its gauge and counter metrics (or only `--metric`): labels with `child_of` fan out under their parent, the others form a cross product; series get Zipf scales from a seeded rank shuffle; gauges are scaled Pareto draws and counters grow by their scale per sample. `--verify-facts` checks, for every label subset, the distinct label-value tuples of the generated series against the description. The `--groups` workload sends the same bytes as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
`--workload-table` now also sends a table's `records` metrics (the multi-grouping `http` and `flows`). Each record is a stateless hash of the seed, the metric and its index: labels are Zipf(`skew`) draws (a child given its parent, value `i` of rank `i`), keys are Zipf ranks, a burst sends `share` of the records to its label value from its own keys, and Pareto values are scaled by their `scaled_by` label's factor (aqpbm-datagen's log-uniform [1, 10]) and by the anomaly factor on the anomaly label's first value. A tick starting at t spreads its records over 10 ms slots in (t, t + 1 s], slot s at t + (s + 1) * 10 ms, and is sent concurrently like gauge/counter ticks, so one feeder can send both kinds. Records are generated inside the encoding tasks. Remote write sends one sample per value field, named `<metric>.<field>`; ClickHouse gets one row per record in a table named after the metric. `--records-per-sec` scales a run down, and `--verify-facts` also compares the shares of each label's heaviest values and of the burst with sketch-bench's `label_shares()`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
…aply A Zipf keeps a dense CDF and a u32 guide entry per value, so a records label's cardinality and a field's keys are capped at 1e8 (1.2 GB), with an error naming the cap; burst keys are drawn uniformly and keep only the 2^53 bound. `--verify-facts` no longer enumerates every label combination of a records metric: per label subset it prints the possible tuples and how many the sampled 1e6 records hold, failing only if they hold more. The share checks are unchanged. The `Workload` doc now says one feeder sends both kinds of metric. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
…equest Concurrent requests split a tick by time slot, so a series' later sample could arrive first and ASAPQuery's increase accumulator, which reads samples in arrival order, took the lower counter value for a reset. A tick's rows are now series-major and requests are cut only between series (the batch size rounded down to whole series, at least one), so each series' samples of a tick arrive in one request in timestamp order; requests stay concurrent. Prometheus therefore needs no out-of-order window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
Table-mode gauge and counter metrics are now series-major too: each metric's tick is cut into requests only between series, so a series' samples of a tick arrive in one request, in timestamp order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
Gauge and counter requests hold whole series, as on feat/paced-feeder-facts; records requests are still cut anywhere, since no records query reads a series in arrival order and Prometheus is not a target for them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae
5 of 6 tasks
Contributor
Code review
Nits: |
A tick straddling a 1s boundary can close a window before its other series' samples arrive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…at-ms Feeders launched at different moments can share one aligned event-time origin: data is stamped from --start-ms but sent from --send-at-ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to feat/paced-feeder-facts
# Conflicts: # asap-tools/data-sources/paced-feeder/src/encode.rs # asap-tools/data-sources/paced-feeder/src/main.rs # asap-tools/data-sources/paced-feeder/src/workload.rs
# Conflicts: # asap-tools/data-sources/paced-feeder/src/main.rs
…ords # Conflicts: # asap-tools/data-sources/paced-feeder/README.md # asap-tools/data-sources/paced-feeder/src/encode.rs # asap-tools/data-sources/paced-feeder/src/main.rs # asap-tools/data-sources/paced-feeder/src/table.rs # asap-tools/data-sources/paced-feeder/src/workload.rs
milindsrivastava1997
changed the base branch from
feat/paced-feeder-facts
to
main
October 14, 2026 17:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on the workload-table feeder PR (base branch
feat/paced-feeder-facts).Summary
The feeder now generates sketch-bench's multi-grouping data:
type: "records"metrics (http,flows, from sketch-bench#209'se2e.metrics). Each record carries labels and several value fields. Record n depends only on the seed, the metric name and n.(i+1)^-skew, a child is drawn given its parent, and child values name their parent. This mirrors sketch-bench'slabel_shares.user_id,src_ip): Zipf rank overkeys, drawn by binary search over a precomputed CDF with a guide table.share, the record'sdst_subnetis set to the burst value and its key is drawn uniformly from a separate range ofkeysburst keys.1000 · Pareto(a)(scale fromconfigs/datagen/hydra_http_latency.yaml), times the service's factor10^u(aqpbm-datagen'sscale_range[1, 10]), times 10 for the anomaly endpoint"0.0".<metric>.<field>(e.g.http.latency), which is how ASAPQuery's SQL-mode router matchestable.value_column. Prometheus is not a target for records metrics.ts, the labels, then the value fields (Float64). See the README.--records-per-secscales records metrics down.--verify-factsalso checks each label's top shares and the burst share over 1e6 generated records, within 5 standard errors.alltable (classic and records metrics together).Testing
multigroup-shared1: every label subset matches (http 15, up to 10,000 combinations; flows 7, up to 3e6). The shares matchlabel_shares(e.g. service 0: 0.29841 expected, 0.29847 generated). The burst gets 5.03% of the records.dst_subnet=999share 0.0500, exactly 10,000 burst keys.precompute_engine(default lateness), http at 20k records/s via remote write: 0 late drops, and all 200,000http.latencysamples were routed to the aggregation.--records-per-secor spread the sinks.🤖 Generated with Claude Code
https://claude.ai/code/session_01AnJ7LocWxguh3q4QWkCYae