Skip to content

QueueManager Shard-Level Coalescing - #5

Draft
dashpole wants to merge 2 commits into
mainfrom
prototype/opt-b-queuemanager-coalescing
Draft

QueueManager Shard-Level Coalescing#5
dashpole wants to merge 2 commits into
mainfrom
prototype/opt-b-queuemanager-coalescing

Conversation

@dashpole

Copy link
Copy Markdown
Owner

Why is this change necessary?

Possible fix for prometheus#17857

The Prometheus Remote Write 2.0 (PRW 2.0) specification states:

"At least one element in samples or in histograms MUST be provided. A TimeSeries MUST NOT include both samples and histograms."

Currently, Prometheus TSDB writes samples and exemplars into separate WAL records. Remote Write QueueManager ingests them as independent queue items (tSample vs tExemplar). When serializing for PRW 2.0 in populateV2TimeSeries, tExemplar emits a writev2.TimeSeries message with attached exemplars but 0 samples and 0 histograms. This violates the PRW 2.0 specification, causing downstream PRW 2.0 receivers (OTel Collector, Mimir, Google Cloud Managed Prometheus) to reject payloads or fail parsing.

Previous attempts (such as PR prometheus#18014) attempted to match exemplars across a single popped batch slice, which dropped exemplars whenever samples and exemplars landed in adjacent batches.

What does this PR do?

This PR implements a QueueManager Shard-Level Coalescing Window, resolving the specification violation completely within storage/remote/ with zero TSDB or WAL on-disk modifications:

  1. Lock-Free Shard Coalescing Ring (storage/remote/shard_coalescer.go):

    • Embeds a shardCoalescer into each shard queue worker with a pre-allocated circular ring buffer (default 2,048 slots) and 64-bit slot generation counters (uint64) to eliminate dangling index risks on buffer wrap-around.
    • Uses an integer-keyed series map index (map[chunks.HeadSeriesRef]coalescerIndexEntry) guaranteeing zero heap string allocations on the hot ingestion path.
  2. Exact Scrape Timestamp Matching ($\le 50\text{ms}$):

    • Enforces an exact timestamp correlation window: an exemplar matches a sample/histogram if and only if $\text{sample.SeriesRef} == \text{exemplar.SeriesRef} \text{ and } |\text{sample.T} - \text{exemplar.T}| \le 50\text{ms}$.
    • Forbids cross-scrape matching, preventing trace attribution corruption across scrape intervals.
  3. Strict PRW 2.0 Invariants & Drop Accounting:

    • populateV2TimeSeries populates writev2.TimeSeries containing $\ge 1$ Sample or Histogram with attached exemplars. Standalone exemplar series are eliminated.
    • If an exemplar exceeds the lookback deadline or series terminates without a matching sample, it is evicted and tracked in prometheus_remote_write_unmatched_exemplars_dropped_total (never emitting an invalid 0-sample series and never retransmitting duplicate samples).
  4. Resharding Synchronization:

    • QueueManager.reshardLoop() flushes active batches and drains shard coalescers during dynamic shard scaling, preventing orphaned buffered exemplars.

Verification & Testing

  • go test -v -race ./storage/remote/... (All PASS)
  • TestQueueManager_PRW2_Coalescing: Verifies all sample arrival orders, native histograms, and float histograms.
  • TestQueueManager_100kSeriesChurn_HeapStability: Ingested 100,000 distinct series under continuous churn; confirmed stable bounded heap memory (~13.6 MB).
  • BenchmarkQueueManager_PRW2: Validated minimal allocation footprint on PRW 2.0 sending path.

Implement Prototype Option B for Prometheus Issue prometheus#17857 to correlate, buffer,
and coalesce samples and exemplars in QueueManager shard worker queues prior to
PRW 2.0 protobuf serialization.

- Introduce shardCoalescer with a fixed-size circular ring buffer (2,048 entries),
  slot generation tracking, and exact scrape timestamp matching (<= 50ms).
- Support sample-first and exemplar-first ingestion for float samples, native
  histograms, and float histograms with zero string allocations on the hot path.
- Enforce PRW 2.0 specification invariants (zero empty TimeSeries, zero duplicate
  samples, drop unmatched exemplars on deadline with metric instrumentation).
- Synchronize lifecycle and drainage during dynamic resharding.
- Add unit tests, resharding concurrency tests with -race, and 100k churn benchmarks.
@dashpole dashpole changed the title Prototype/opt b queuemanager coalescing QueueManager Shard-Level Coalescing Aug 27, 2026
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.

1 participant