Optimizing NFS Read Cache Performance for Small Files on Debian: Client-Side Caching Configuration and Alternatives


3 views

When working with NFS (Network File System) on Debian, the client-side caching behavior is primarily governed by the nfs kernel module and its interaction with the Linux page cache. For small files that are frequently read, these caching mechanisms become critical for performance.

The default NFS implementation uses the following cache layers:

1. Attribute cache (acregmin/acregmax/acdirmin/acdirmax)
2. Data cache (via Linux page cache)
3. Directory cache (dcache)

To optimize NFS read caching for small files on Debian, you'll want to adjust these important parameters in /etc/nfs.conf or via mount options:

# Example mount options for improved caching:
mount -t nfs4 -o \
  rw,hard,intr,rsize=65536,wsize=65536,\
  acregmin=60,acregmax=60,\
  acdirmin=60,acdirmax=60,\
  nocto,actimeo=60 \
  server:/share /mnt/nfs

Explanation of critical options:

  • actimeo: Sets all attribute cache timeouts (replaces acregmin/max and acdirmin/max)
  • nocto: Disables close-to-open consistency, improving cache performance
  • rsize/wsize: Optimal for small files (adjust based on your workload)

Use these commands to monitor your NFS cache performance:

# Check NFS statistics
nfsstat -c

# View kernel slab cache info (includes NFS cache)
cat /proc/slabinfo | grep nfs

# Monitor page cache usage
cat /proc/meminfo | grep -E 'Cached|Buffers'

If NFS caching proves insufficient for your small-file workload, consider these alternatives:

# Option 1: Use cachefilesd for persistent caching
sudo apt install cachefilesd
echo "RUN=yes" > /etc/default/cachefilesd
echo "brun 10% bcull 7% bstop 3% frun 10% fcull 7% fstop 3%" > /etc/cachefilesd.conf
systemctl start cachefilesd

# Mount with fsc option:
mount -t nfs4 -o fsc server:/share /mnt/nfs

Another approach is to use FS-Cache which provides persistent caching across reboots:

# Configure FS-Cache
modprobe cachefiles
echo "cachefiles" >> /etc/modules

Here's a simple Python script to test small file read performance:

import time
import os

def test_nfs_performance(dir_path, num_files=1000):
    start = time.time()
    for i in range(num_files):
        with open(f"{dir_path}/test_{i}.txt", 'r') as f:
            f.read()
    duration = time.time() - start
    print(f"Read {num_files} files in {duration:.2f} seconds")
    print(f"Average: {duration/num_files*1000:.2f} ms per file")

test_nfs_performance("/mnt/nfs/small_files")

For extreme workloads, consider these kernel parameters in /etc/sysctl.conf:

# Increase NFSd threads
sunrpc.tcp_slot_table_entries = 128
sunrpc.udp_slot_table_entries = 128

# Boost virtual memory performance for caching
vm.vfs_cache_pressure = 50
vm.swappiness = 10

Remember to load these changes with sysctl -p.

If after all optimizations NFS still doesn't meet your needs, consider:

  • GlusterFS: Better for small files with its distributed hash table
  • sshfs: Simpler alternative with local caching via FUSE
  • Syncthing: For bidirectional synchronization needs

Each has its own caching characteristics that might better suit your small-file-heavy workload.


When dealing with NFS-mounted directories on Debian, the client-side caching behavior is primarily controlled by these mechanisms:

  • Attribute caching (acregmin/acregmax/acdirmin/acdirmax)
  • Page cache (Linux virtual filesystem layer)
  • NFS client readahead

To optimize for small file reads, modify these parameters in /etc/nfs.conf or via mount options:

# Example /etc/nfs.conf adjustments
[nfsd]
threads=16

[nfsclnt]
acregmin=60
acregmax=120
acdirmin=60
acdirmax=120
rsize=32768
wsize=32768

For mount-specific tuning:

# /etc/fstab entry example
server:/export /mnt/nfs nfs rw,sync,noatime,acregmin=60,acregmax=120,acdirmin=60,acdirmax=120,rsize=32k,wsize=32k 0 0

Use these commands to monitor cache effectiveness:

# Check NFS statistics
nfsstat -c

# Monitor page cache usage
cat /proc/meminfo | grep -E 'Cached|Buffers'

# Measure actual performance
time find /mnt/nfs -type f -exec cat {} + > /dev/null

When NFS caching isn't sufficient, consider:

# Option 1: Local mirror with inotify-tools
inotifywait -m -r /mnt/nfs | while read path action file; do
    rsync -az --delete /mnt/nfs/ /local/mirror/
done

# Option 2: CacheFilesD (kernel 2.6.30+)
modprobe cachefiles
echo "brun 10% bcull 7% bstop 3%" > /proc/fs/cachefiles/caches

Watch for these indicators of suboptimal caching:

  • High nfsstat -c getattr counts
  • Frequent disk reads in iotop
  • Growing memory usage without corresponding cache growth