app/vmselect/promql: adjust memory limits calculations for incremental aggregate functions

Incremental aggregate functions don't keep all the selected time series in memory -
they keep only up to GOMAXPROCS time series for incremental aggregations.

Take into account that the number of time series in RAM can be higher if they are split
into many groups with `by (...)` or `without (...)` modifiers.

This should reduce the number of `not enough memory for processing ... data points` false
positive errors.
This commit is contained in:
Aliaksandr Valialkin 2019-11-08 18:45:25 +02:00
parent d888b21657
commit 63b05c0b9f

View file

@ -595,7 +595,18 @@ func evalRollupFuncWithMetricExpr(ec *EvalConfig, name string, rf rollupFunc, me
// Verify timeseries fit available memory after the rollup. // Verify timeseries fit available memory after the rollup.
// Take into account points from tssCached. // Take into account points from tssCached.
pointsPerTimeseries := 1 + (ec.End-ec.Start)/ec.Step pointsPerTimeseries := 1 + (ec.End-ec.Start)/ec.Step
rollupPoints := mulNoOverflow(pointsPerTimeseries, int64(rssLen*len(rcs))) timeseriesLen := rssLen
if iafc != nil {
// Incremental aggregates require hold only GOMAXPROCS timeseries in memory.
timeseriesLen = runtime.GOMAXPROCS(-1)
if iafc.ae.Modifier.Op != "" {
// Increase the number of timeseries for non-empty group list: `aggr() by (something)`,
// since each group can have own set of time series in memory.
// Estimate the number of such groups is lower than 100 :)
timeseriesLen *= 100
}
}
rollupPoints := mulNoOverflow(pointsPerTimeseries, int64(timeseriesLen*len(rcs)))
rollupMemorySize := mulNoOverflow(rollupPoints, 16) rollupMemorySize := mulNoOverflow(rollupPoints, 16)
rml := getRollupMemoryLimiter() rml := getRollupMemoryLimiter()
if !rml.Get(uint64(rollupMemorySize)) { if !rml.Get(uint64(rollupMemorySize)) {