Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
Back to tool/Back to issues
#14089·skywalking

[Feature] BanyanDB: time-bucket grouping, standalone + distributed

Author: hanahmilyCreated Sep 17, 2026Updated Sep 17, 2026
Labelsfeaturedatabase

Part 2 of 5 of the tag aggregation and time bucketing design, shipped in apache/skywalking-banyandb#1360.

Design references: §5.3 Resolving the bucket width · §7.2 Time-bucket grouping · §10 Compatibility (mixed-version) · §12 Delivery order (stages 2–3)

Depends on: #14088 (API foundation + tag binding).

Scope

Standalone

  • bucketStart (mirrors getWindowStart, sliding_window.go:302); §5.3 width resolution (request → measure interval → reject; deliberately no multiple-of-interval rule, since Measure.interval is a declared cadence, not an enforced invariant).
  • BatchTimeBucket streaming operator on the part-scan path: one bucket's groups live at a time, flushed on bucket advance; monotonicity guard (a row whose bucket regresses is a loud error, not a silent duplicate).
  • Non-streaming map fallback for index-mode measures, chosen on measureSchema.GetIndexMode() — never a runtime guess — because the index path returns before the ordering guarantee streaming depends on is established.
  • Conditional D2 reversal: buildAggOutputLayout re-emits RoleTimestamp (set to bucket start) only when a bucket key is present; the existing "aggregation drops the timestamp" assertion stays correct for the unbucketed case.
  • Analyzer guard rejecting a bucketed request whose resolved ordering isn't time-ascending (protects the streaming precondition).

Distributed

  • Node template carries the bucket key; each node floors independently, no coordination needed.
  • distributedGroupByTagNames/resolveKeyIndices carry/resolve the bucket as the leading key.
  • Liaison k-way merge on the bucket (nodes stream bucket-ascending, so the liaison never holds more than one bucket per node stream).
  • Mixed-version guard (§10): a bucketed response missing the RoleTimestamp column (an old node that ignored the new proto field) is a hard error, not a silent whole-range collapse.

Out of scope

  • COUNT_DISTINCT — see #14090.
  • Run-folding / metadata-only-scan performance work — separate, optional follow-up issue.

Test / Definition of done

  • bucketStart vs. getWindowStart agreement table, including a boundary timestamp (ts % width == 0) and a negative one.
  • §5.3 table as literal test cases, including "width not a multiple of the interval → accepted."
  • plan/build_test.go:221's D2 assertion stays for the unbucketed case, gains a bucketed sibling asserting the timestamp is present and equals the bucket start.
  • Streaming operator: bucket closure releases live state (not just output), monotonicity guard fires on out-of-order input, first bucket emits before scan end (pipelining), applyMeasureQueryOrdering's Order == nil → orderByTS = true default is pinned.
  • Index-mode: non-chronological input (timestamps arriving A, B, A) still produces one correct result per bucket — proves it took the map, not the streaming path.
  • Distributed: node template carries the bucket key; liaison k-way merge correctness over synthetic multi-node frames; mixed-version simulation (a synthetic node response without RoleTimestamp) triggers the hard error; standalone vs. distributed agreement on the same bucketed fixture.

Source: apache/skywalking

View original on GitHubView discussion on GitHub