use fadvise to control Linux page-cache (#13312)

This PR brings two optimizations mainly
for page-cache build-up and how to avoid
getting OOM killed in the process. Although
these memories are reclaimable Linux is not
fast enough to reclaim them as needed on a
very busy system. fadvise is a system call
implemented in Linux to advise page-cache to
avoid overload as we get significant amount
of requests on the server.

- FADV_SEQUENTIAL tells that all I/O from now
  is going to be sequential, allowing for more
  resposive throughput.

- FADV_NOREUSE tells kernel to start removing
  things for this 'fd' from page-cache.
This commit is contained in:
Harshavardhana
2021-09-28 10:02:56 -07:00
committed by GitHub
parent dd5804c10e
commit 38027c8f52
6 changed files with 73 additions and 1 deletions

View File

@@ -387,7 +387,7 @@ func (s *xlStorage) SetDiskLoc(poolIdx, setIdx, diskIdx int) {
func (s *xlStorage) Healing() *healingTracker {
healingFile := pathJoin(s.diskPath, minioMetaBucket,
bucketMetaPrefix, healingTrackerFilename)
b, err := ioutil.ReadFile(healingFile)
b, err := xioutil.ReadFile(healingFile)
if err != nil {
return nil
}
@@ -410,6 +410,12 @@ func (s *xlStorage) readMetadata(ctx context.Context, itemPath string) ([]byte,
if err != nil {
return nil, err
}
if err := disk.Fadvise(f, disk.FadvSequential); err != nil {
return nil, err
}
defer disk.Fadvise(f, disk.FadvNoReuse)
defer f.Close()
stat, err := f.Stat()
if err != nil {
@@ -1228,6 +1234,10 @@ func (s *xlStorage) readAllData(volumeDir string, filePath string) (buf []byte,
}
return nil, err
}
if err := disk.Fadvise(f, disk.FadvSequential); err != nil {
return nil, err
}
defer disk.Fadvise(f, disk.FadvNoReuse)
r := &odirectReader{f, nil, nil, true, true, s, nil}
defer r.Close()
buf, err = ioutil.ReadAll(r)
@@ -1547,6 +1557,11 @@ func (s *xlStorage) ReadFileStream(ctx context.Context, volume, path string, off
return nil, errIsNotRegular
}
// Enable sequential read access pattern - only applicable on Linux.
if err := disk.Fadvise(file, disk.FadvSequential); err != nil {
return nil, err
}
if offset == 0 {
or := &odirectReader{file, nil, nil, true, false, s, nil}
if length <= smallFileThreshold {
@@ -1565,6 +1580,7 @@ func (s *xlStorage) ReadFileStream(ctx context.Context, volume, path string, off
io.Reader
io.Closer
}{Reader: io.LimitReader(file, length), Closer: closeWrapper(func() error {
disk.Fadvise(file, disk.FadvNoReuse)
return file.Close()
})}