Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to control the aggregation type for the SelectSeries API #2758

Merged
merged 11 commits into from
Dec 4, 2023

Conversation

aleks-p
Copy link
Contributor

@aleks-p aleks-p commented Nov 24, 2023

Adds an optional "aggregation" param to the SelectSeries API, allowing to switch between "sum" (the default), "avg" and "first" (used mostly internally). Other aggregation functions can be added in the future. Right now it only impacts the time series, but I will see how much work it would be (and how expensive it is) to apply it to the flamegraph as well.

A PR in Grafana will follow where we expose this in the Explore view like this:

Screenshot 2023-11-24 at 13 19 18

@aleks-p aleks-p requested a review from a team as a code owner November 24, 2023 17:58
}
return j + 1
}

type TimeSeriesAggregator interface {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name could be a bit confusing since we also have

type Aggregator[T any] struct {

I think their purpose is slightly different but putting that in the name is hard. Any thoughts @kolesnikovae?

Copy link
Collaborator

@kolesnikovae kolesnikovae Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion as these types are not supposed to be used in the same context. The key difference is that distributor/aggregator operates on real-time data streams, therefore we could call it e.g. StreamAggregator

}
return j + 1
}

type TimeSeriesAggregator interface {
Copy link
Collaborator

@kolesnikovae kolesnikovae Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion as these types are not supposed to be used in the same context. The key difference is that distributor/aggregator operates on real-time data streams, therefore we could call it e.g. StreamAggregator

api/ingester/v1/ingester.proto Outdated Show resolved Hide resolved
Comment on lines 188 to 192
func (a *avgTimeSeriesAggregator) Add(ts int64, value float64) {
a.ts = ts
a.sum += value
a.count++
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to make sure I fully understand the aggregation and its relation to grouping. I'm sorry if I got it wrong :)

Given two series (with just one value each):

{pod=a, endpoint=x}: { ts_1, 8 }
{pod=a, endpoint=y}: { ts_1, 4 }

Given a query avg (group) by pod. What would be the result: {pod=a} 12 or {pod=a} 6?

My understanding is that the aggregator gets two values at input (from seriesBuilder):

{pod=a}: { ts_1, 4 }, { ts_1, 8 }

Which then will be averaged and the result will be 6. I'm not very sure this is what users expect (despite it is literally the average value)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be {pod=a} 6 and I am not sure either though summing will often make no sense as well, depending on the profile type. There are two aspects to this aggregation:

  1. Reducing samples for the exact same timestamp (happens in series.go, previously either "first" or "sum")
  2. Reducing samples within a step interval (happens in querier.go, previously always "sum")

Honestly I am not sure we need 1. Leaving duplicate samples in and letting 2 handle the aggregation would produce more reliable results (currently in 2 we will do avg of avg at times).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree we should only do 2 to avoid avg of avg. May be only when it's not a sum.

pkg/model/series.go Outdated Show resolved Hide resolved
@aleks-p aleks-p requested a review from a team as a code owner November 27, 2023 12:51
@aleks-p aleks-p removed the request for review from a team November 27, 2023 14:21
Copy link
Contributor

@cyriltovena cyriltovena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I don't know if next step is really to expose this in the UI. I think I would rather default to good value based on the profile type for now WDYT ?

@aleks-p aleks-p force-pushed the feat/select-series-control-aggregation branch from 71f4b36 to 3d7c0de Compare November 30, 2023 21:39
@aleks-p
Copy link
Contributor Author

aleks-p commented Nov 30, 2023

I've simplified things a bit:

  • series merger only does "sum" or "retain" (we no longer discard duplicates)
  • the "first value" aggregator is gone (it was only used in the series merger, but not anymore)

This shouldn't change the behavior for sums, but will make averages a bit better (no avg of avg).

For the frontend part, I will hide the dropdown for now and have it make the decision for "avg" or "sum" behind the scenes.

@aleks-p aleks-p force-pushed the feat/select-series-control-aggregation branch from 3d7c0de to cc46b5f Compare December 4, 2023 12:57
@aleks-p aleks-p merged commit b9966bd into main Dec 4, 2023
19 checks passed
@aleks-p aleks-p deleted the feat/select-series-control-aggregation branch December 4, 2023 13:33
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.

3 participants