From fe4ea30a79be2739e5134f1a7b2b01097586b2a5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 23 Jan 2024 13:46:26 +0200 Subject: [PATCH] app/vmselect/netstorage: limit the size of metricNamesBuf to 32Kb in order to avoid slow path at Go runtime for allocating a byte slice of bigger size See https://github.com/golang/go/blob/704401ffa06c60e059c9e6e4048045b4ff42530a/src/runtime/malloc.go#L11 This also reduces the average memory usage a bit for vmselect and single-node VictoriaMetrics after the commit 508c608062ae93125a50cbdb3b9ca673897445b1 Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5527 --- app/vmselect/netstorage/netstorage.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/vmselect/netstorage/netstorage.go b/app/vmselect/netstorage/netstorage.go index 3c0ccf493c..2b32cb7c82 100644 --- a/app/vmselect/netstorage/netstorage.go +++ b/app/vmselect/netstorage/netstorage.go @@ -1438,6 +1438,11 @@ func (tbfw *tmpBlocksFileWrapper) RegisterAndWriteBlock(mb *storage.MetricBlock, if len(addrs.addrs) == 1 { metricNamesBuf := tbfwLocal.metricNamesBuf + if cap(metricNamesBuf) >= maxFastAllocBlockSize && len(metricNamesBuf)+len(metricName) > cap(metricNamesBuf) { + // Allocate a new metricNamesBuf in order to avoid slow allocation of byte slice + // bigger than maxFastAllocBlockSize bytes at append() below. + metricNamesBuf = make([]byte, 0, maxFastAllocBlockSize) + } metricNamesBufLen := len(metricNamesBuf) metricNamesBuf = append(metricNamesBuf, metricName...) metricNameStr := bytesutil.ToUnsafeString(metricNamesBuf[metricNamesBufLen:]) @@ -3046,3 +3051,8 @@ func (pnc *perNodeCounter) GetTotal() uint64 { } return total } + +// Go uses fast allocations for block sizes up to 32Kb. +// +// See https://github.com/golang/go/blob/704401ffa06c60e059c9e6e4048045b4ff42530a/src/runtime/malloc.go#L11 +const maxFastAllocBlockSize = 32 * 1024