server: set globalCacheSize honoring system limits for max memory. (#2332)

On unix systems it is possible to set max memory used by
running processes using 'ulimit -m' or 'syscall.RLIMIT_AS'.

A process whence exceeds this limit, kernel would pro-actively
kill such a server with OOM. To avoid this problem of defaulting
our cache size to 8GB we should look for if the current system
limits are lower and set the cache size appropriately.
This commit is contained in:
Harshavardhana 2016-07-30 08:50:49 -07:00 committed by Anand Babu (AB) Periasamy
parent 5b86dd7659
commit 8d090a20ce
3 changed files with 42 additions and 1 deletions

View File

@ -203,6 +203,11 @@ func initServerConfig(c *cli.Context) {
// Set maxOpenFiles, This is necessary since default operating
// system limits of 1024, 2048 are not enough for Minio server.
setMaxOpenFiles()
// Set maxMemory, This is necessary since default operating
// system limits might be changed and we need to make sure we
// do not crash the server so the set the maxCacheSize appropriately.
setMaxMemory()
// Do not fail if this is not allowed, lower limits are fine as well.
}

View File

@ -30,7 +30,7 @@ func setMaxOpenFiles() error {
return err
}
// Set the current limit to Max, it is usually around 4096.
// TO increate this limit further user has to manually edit
// TO increase this limit further user has to manually edit
// `/etc/security/limits.conf`
rLimit.Cur = rLimit.Max
err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
@ -43,3 +43,34 @@ func setMaxOpenFiles() error {
}
return nil
}
// Set max memory used by minio as a process, this value is usually
// set to 'unlimited' but we need to validate additionally to verify
// if any hard limit is set by the user, in such a scenario would need
// to reset the global max cache size to be 80% of the hardlimit set
// by the user. This is done to honor the system limits and not crash.
func setMaxMemory() error {
var rLimit syscall.Rlimit
err := syscall.Getrlimit(syscall.RLIMIT_AS, &rLimit)
if err != nil {
return err
}
// Set the current limit to Max, it is default 'unlimited'.
// TO decrease this limit further user has to manually edit
// `/etc/security/limits.conf`
rLimit.Cur = rLimit.Max
err = syscall.Setrlimit(syscall.RLIMIT_AS, &rLimit)
if err != nil {
return err
}
err = syscall.Getrlimit(syscall.RLIMIT_AS, &rLimit)
if err != nil {
return err
}
// Validate if rlimit memory is set to lower
// than max cache size. Then we should use such value.
if rLimit.Cur < globalMaxCacheSize {
globalMaxCacheSize = (80 / 100) * rLimit.Cur
}
return nil
}

View File

@ -24,3 +24,8 @@ func setMaxOpenFiles() error {
// (well, you do but it is based on your resources like memory).
return nil
}
func setMaxMemory() error {
// TODO: explore if Win32 API's provide anything special here.
return nil
}