Skip to content

feat: series-aggregation SDK benchmark (--series-per-sketch) - #53

Merged
zzylol merged 8 commits into
mainfrom
51-series-aggregation-at-each-timestamp
Mar 18, 2026
Merged

zzylol merged 8 commits into
mainfrom
51-series-aggregation-at-each-timestamp

Conversation

@zzylol

@zzylol zzylol commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds --series-per-sketch N flag to e2esdkbench so workers aggregate N series into one sketch before export (using a coarser group.id attribute instead of per-series series.id). When N ≥ total series or N=0, all series collapse into a single sketch.
  • Adds SeriesPerSketch field to the summary JSON/struct so results carry the grouping parameter.
  • Output filenames include _grpN_ suffix when N≠1 (e.g. ddsketch_grp100_50000mps_summary.json) preserving backward compatibility with existing bench_sdk_e2e.sh runs.
  • New script otel_collector_benchmark/bench_series_agg.sh sweeps over configurable --groups values against a single baseline run, always using the no-op collector (nopcol). Produces per-run timeseries CSVs, summary JSONs, collector resource CSVs, and a combined aggregate_summary.csv with a bw_reduction_vs_baseline_pct column.

Benchmark Results

Full e2e run: 50,000 MPS · 1,000 series · 60s duration · nopcol collector

Bandwidth (avg KB/s) and reduction vs raw baseline

Sketch grp1 (no agg) grp10 grp100 grp1000
baseline (raw) 2,586 KB/s — 0%
ddsketch 2,042 KB/s — 24.8% 231 KB/s — 91.5% 24 KB/s — 99.1% 3.2 KB/s — 99.9%
kll 1,127 KB/s — 56.4% 128 KB/s — 95.0% 14.9 KB/s — 99.4% 2.4 KB/s — 99.9%
hll 15,843 KB/s — −513% 1,586 KB/s — 38.6% 160 KB/s — 93.8% 17 KB/s — 99.3%

SDK CPU % at each group size

Sketch grp1 grp10 grp100 grp1000
baseline (raw) 97.5%
ddsketch 47.3% 33.7% 32.2% 17.4%
kll 35.7% 26.5% 27.9% 10.5%
hll 39.2% 22.0% 21.0% 10.6%

Avg heap (MB) at each group size

Sketch grp1 grp10 grp100 grp1000
baseline (raw) 22 MB
ddsketch 22.6 MB 3.5 MB 2.6 MB 2.3 MB
kll 14.1 MB 3.3 MB 2.5 MB 2.5 MB
hll 92.4 MB 9.2 MB 2.8 MB 2.5 MB

Key observations

  • KLL grp1 already saves 56% bandwidth vs raw with no grouping — smaller sketch encoding than ddsketch at this cardinality.
  • HLL grp1 is counterproductive (+513% BW, 92 MB heap) — HLL registers are large relative to a raw sample at 1,000 series; aggregation only pays off at grp10+.
  • Grouping just 10 series per sketch cuts bandwidth by 88–95% across all sketch types.
  • All sketches converge to near-zero bandwidth at grp1000, with SDK CPU dropping to ~10%.

Test plan

  • go build ./cmd/e2esdkbench passes
  • Full benchmark run completed for all sketch types (ddsketch, kll, hll) at 50k MPS, groups 1/10/100/1000
  • Confirm existing bench_sdk_e2e.sh behaviour unchanged (no --series-per-sketch flag → default 1 → original filenames)

🤖 Generated with Claude Code

Extend e2esdkbench with --series-per-sketch flag so N series can be
collapsed into one sketch before export, reducing OTLP data-point count
from series → series/N. Add bench_series_agg.sh to sweep group sizes
against a baseline (raw per-series gauges), both hitting a no-op
collector, recording SDK bandwidth, CPU, heap and collector CPU/RSS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zzylol zzylol linked an issue Mar 17, 2026 that may be closed by this pull request
zzylol and others added 7 commits March 18, 2026 18:25
- Rename GROUPS→SWEEP_GROUPS in bench_series_agg.sh (bash read-only var conflict)
- Fix readerInterval logic in e2esdkbench (baseline uses workerInterval, sketches use 1s)
- Sync all patch folders with current submodule state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
backup_all.sh uses rm -rf when copying untracked directories from
submodules, wiping config-window.yaml and config-bench.yaml from patch
folders. Restore the 8 deleted files from the previous commit so
bench_sdk_e2e.sh can still find its collector configs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace rm -rf + cp -R with mkdir -p + cp -R src/. dest/ so that
patch-only files (e.g. config-window.yaml) are preserved when an
untracked directory in the submodule triggers a directory-level copy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- bench_series_agg.sh: rename GROUPS→SWEEP_GROUPS (bash read-only var)
- e2esdkbench/main.go: fix readerInterval — sketches use 1s, baseline
  uses workerInterval (was inverted)
- cmd/kll/build-config.yaml: uncomment sketchlib-go replace so builder
  picks up local Reset() instead of stale module cache
- cmd/hllcol/build-config.yaml: add sketchlib-go replace (same fix)
- Sync patch dirs and rebuilt KLL binary

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…th replaces)

Pull main (49890c7) which includes merged add-reset-methods (Reset() on
KLL and HLL) and aligned-sketch-implementation. Update all go.mod/go.sum
that previously pinned to /mydata/sketchlib-go:

- processor/{kll,hll,countminsketck,countsketch}processor
- opentelemetry-go sdk/metric and otlpmetric{grpc,http} exporters
- opentelemetry-app

Remove local replace directives; remove local path from KLL and HLL
builder configs. All 4 collector binaries and e2esdkbench rebuild clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zzylol
zzylol merged commit 665ffa8 into main Mar 18, 2026
@zzylol
zzylol deleted the 51-series-aggregation-at-each-timestamp branch March 18, 2026 23:51
SieDeta pushed a commit that referenced this pull request Apr 17, 2026
…-timestamp

feat: series-aggregation SDK benchmark (--series-per-sketch)
zzylol added a commit that referenced this pull request May 5, 2026
…ib-go rename adaptation (#262)

Two independent blockers prevented `asap/fake-exporter:dev` from
rebuilding off main HEAD; both fixed.

## Blocker A — missing Go bindings for opentelemetry-proto-patch

The patched `metrics.proto` adds five sketch message types (DDSketch /
KLLSketch / CountSketch / CountMinSketch / HLLSketch) on top of upstream
v1.9.0, but the regenerated `.pb.go` files were never committed. Every
build hit `undefined: mpb.Metric_Ddsketch / mpb.DDSketchDataPoint / ...`
in the patched OTLP transform layer.

Fix: regenerated the Go bindings via the upstream `make gen-go` recipe
(otel/build-protobuf:0.9.0 image, `--go_out=plugins=grpc`) over a clean
v1.9.0 + the patched `.proto` files; committed all 10 `.pb.go` outputs
(11,385 lines total) under `opentelemetry-proto-patch/gen/go/...`.
Updated `.gitignore` to track that subtree. Added an explicit
`go.opentelemetry.io/proto/otlp` replace in `deploy/fake-exporter/go.mod`
pointing at the gen tree (the dependency module's replace isn't honored
from a downstream main module). Updated `Dockerfile.fake-exporter` to
copy `opentelemetry-proto/` into the build context so the relative
replace path resolves. Wrote `opentelemetry-proto-patch/REGEN.md` with
the full regeneration recipe.

## Blocker B — sketchlib-go API rename refactor (PR #53) absorption

The patched OTLP transform files referenced `metricdata.KLLSketchEncodingGob`,
`metricdata.CountSketchEncodingGob`, `metricdata.CountMinSketchEncodingGob`
and the corresponding `mpb.*_ENCODING_GOB` enum values. Those names were
renamed to `*EncodingProto` / `*EncodingDelta` and `*_ENCODING_PROTO` /
`*_ENCODING_DELTA` by the gob→proto encoding rename (commit b031975) and
by sketchlib-go PR #53.

Fix: updated KLL/CountSketch/CountMinSketch encoding switches in both
the otlpmetricgrpc and otlpmetrichttp transform packages to dispatch on
the post-rename names. CountSketch/CountMinSketch get the additional
Delta arm matching the sketch wire's sparse-delta path; KLL keeps a
single Proto arm (no delta defined for KLL).

The sketchlib-go API renames per PR #53
(`Add`/`Insert` → `Update` on per-value, `InsertValue` → `UpdateValue` on
HLL, `Insert(input)` / `OctoInsert` → `Update`, `EstimateCardinality()`
→ `Estimate()` on HLL, `GetValueAtQuantile` → `Quantile` on DDSketch,
`InsertWeight`/`InsertBatch`/`InsertHashes`/`BulkInsert` →
`UpdateWeight`/`UpdateBatch`/`UpdateHashes`/`BulkUpdate`) were already
absorbed into the patched `sdk/metric/internal/aggregate/{hllsketch,
kllsketch,countminsketch,countsketch,ddsketch}.go` and
`asap-precompute-go/sketches/hll.go` before this round; the rebuild
verifies they're correct.

## Verification

- `docker builder prune -af` then `DOCKER_BUILDKIT=1 docker build -f
  deploy/docker/Dockerfile.fake-exporter --build-context
  sketchlib-go=/path/to/sketchlib-go -t asap/fake-exporter:dev .` → clean
  cold-cache build.
- `go build ./...` and `go test ./...` clean in
  `opentelemetry-go/sdk/metric/` and `asap-precompute-go/`.
- Recreated against the live E0 stack (b3-delta + e2e-overlay, N=1):
  `docker compose ... up -d --force-recreate fake-exporter` → clean
  startup logs, container Up 30s with no errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

series aggregation at each timestamp

1 participant