mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
honor requests_max based on cgroup_limits if configured (#13673)
container limits would not be properly honored in our current implementation, mem.VirtualMemory() function only reads /proc/meminfo which points to the host system information inside the container.
This commit is contained in:
parent
8378bc9958
commit
5b68f8ea6a
@ -18,7 +18,10 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -48,6 +51,46 @@ type apiConfig struct {
|
|||||||
deleteCleanupInterval time.Duration
|
deleteCleanupInterval time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cgroupLimitFile = "/sys/fs/cgroup/memory/memory.limit_in_bytes"
|
||||||
|
|
||||||
|
func cgroupLimit(limitFile string) (limit uint64) {
|
||||||
|
buf, err := ioutil.ReadFile(limitFile)
|
||||||
|
if err != nil {
|
||||||
|
return 9223372036854771712
|
||||||
|
}
|
||||||
|
limit, err = strconv.ParseUint(string(buf), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 9223372036854771712
|
||||||
|
}
|
||||||
|
return limit
|
||||||
|
}
|
||||||
|
|
||||||
|
func availableMemory() (available uint64) {
|
||||||
|
available = 8 << 30 // Default to 8 GiB when we can't find the limits.
|
||||||
|
|
||||||
|
if runtime.GOOS == "linux" {
|
||||||
|
available = cgroupLimit(cgroupLimitFile)
|
||||||
|
|
||||||
|
// No limit set, It's the highest positive signed 64-bit
|
||||||
|
// integer (2^63-1), rounded down to multiples of 4096 (2^12),
|
||||||
|
// the most common page size on x86 systems - for cgroup_limits.
|
||||||
|
if available != 9223372036854771712 {
|
||||||
|
// This means cgroup memory limit is configured.
|
||||||
|
return
|
||||||
|
|
||||||
|
} // no-limit set proceed to set the limits based on virtual memory.
|
||||||
|
|
||||||
|
} // for all other platforms limits are based on virtual memory.
|
||||||
|
|
||||||
|
memStats, err := mem.VirtualMemory()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
available = memStats.Available / 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (t *apiConfig) init(cfg api.Config, setDriveCounts []int) {
|
func (t *apiConfig) init(cfg api.Config, setDriveCounts []int) {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
@ -64,14 +107,7 @@ func (t *apiConfig) init(cfg api.Config, setDriveCounts []int) {
|
|||||||
|
|
||||||
var apiRequestsMaxPerNode int
|
var apiRequestsMaxPerNode int
|
||||||
if cfg.RequestsMax <= 0 {
|
if cfg.RequestsMax <= 0 {
|
||||||
var maxMem uint64
|
maxMem := availableMemory()
|
||||||
memStats, err := mem.VirtualMemory()
|
|
||||||
if err != nil {
|
|
||||||
// Default to 8 GiB, not critical.
|
|
||||||
maxMem = 8 << 30
|
|
||||||
} else {
|
|
||||||
maxMem = memStats.Available / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// max requests per node is calculated as
|
// max requests per node is calculated as
|
||||||
// total_ram / ram_per_request
|
// total_ram / ram_per_request
|
||||||
|
Loading…
Reference in New Issue
Block a user