From 9d79a3a99da734ac4f9dd748a05ff2c916926b46 Mon Sep 17 00:00:00 2001
From: Aliaksandr Valialkin <valyala@gmail.com>
Date: Fri, 14 Aug 2020 19:12:10 +0300
Subject: [PATCH] lib/memory: add `-memory.allowedBytes` command-line flag for
 setting absolute memory limit for VictoriaMetrics caches

---
 lib/memory/memory.go | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/lib/memory/memory.go b/lib/memory/memory.go
index f9982098cf..d918caa0e0 100644
--- a/lib/memory/memory.go
+++ b/lib/memory/memory.go
@@ -8,9 +8,16 @@ import (
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 )
 
-var allowedMemPercent = flag.Float64("memory.allowedPercent", 60, "Allowed percent of system memory VictoriaMetrics caches may occupy. "+
-	"Too low value may increase cache miss rate, which usually results in higher CPU and disk IO usage. "+
-	"Too high value may evict too much data from OS page cache, which will result in higher disk IO usage")
+var (
+	allowedPercent = flag.Float64("memory.allowedPercent", 60, "Allowed percent of system memory VictoriaMetrics caches may occupy. "+
+		"See also -memory.allowedBytes. "+
+		"Too low value may increase cache miss rate, which usually results in higher CPU and disk IO usage. "+
+		"Too high value may evict too much data from OS page cache, which will result in higher disk IO usage")
+	allowedBytes = flag.Int("memory.allowedBytes", 0, "Allowed size of system memory VictoriaMetrics caches may occupy. "+
+		"This option overrides -memory.allowedPercent if set to non-zero value. "+
+		"Too low value may increase cache miss rate, which usually results in higher CPU and disk IO usage. "+
+		"Too high value may evict too much data from OS page cache, which will result in higher disk IO usage")
+)
 
 var (
 	allowedMemory   int
@@ -24,15 +31,19 @@ func initOnce() {
 		// Do not use logger.Panicf here, since logger may be uninitialized yet.
 		panic(fmt.Errorf("BUG: memory.Allowed must be called only after flag.Parse call"))
 	}
-	if *allowedMemPercent < 1 || *allowedMemPercent > 200 {
-		logger.Panicf("FATAL: -memory.allowedPercent must be in the range [1...200]; got %f", *allowedMemPercent)
-	}
-	percent := *allowedMemPercent / 100
-
 	mem := sysTotalMemory()
-	allowedMemory = int(float64(mem) * percent)
+	if *allowedBytes <= 0 {
+		if *allowedPercent < 1 || *allowedPercent > 200 {
+			logger.Panicf("FATAL: -memory.allowedPercent must be in the range [1...200]; got %f", *allowedPercent)
+		}
+		percent := *allowedPercent / 100
+		allowedMemory = int(float64(mem) * percent)
+	} else {
+		allowedMemory = *allowedBytes
+	}
 	remainingMemory = mem - allowedMemory
-	logger.Infof("limiting caches to %d bytes, leaving %d bytes to the OS according to -memory.allowedPercent=%g", allowedMemory, remainingMemory, *allowedMemPercent)
+	logger.Infof("limiting caches to %d bytes, leaving %d bytes to the OS according to -memory.allowedPercent=%f and -memory.allowedBytes=%d",
+		allowedMemory, remainingMemory, *allowedPercent, *allowedBytes)
 }
 
 // Allowed returns the amount of system memory allowed to use by the app.