温馨提示×

centos readdir怎样缓存

小樊
42
2026-09-15 06:54:03
栏目: 智能运维

在 CentOS(以及一般 Linux)上,readdir 本身是由内核和 glibc 实现的,应用程序不能直接“缓存 readdir”,但可以从系统层、库层、应用层多个角度来做目录读取缓存。下面按常见场景说明。


一、理解 readdir 的缓存位置

readdir 调用路径大致是:

应用 (readdir)
  -> glibc
    -> getdents / getdents64 (syscall)
      -> 内核 VFS
        -> 文件系统 (ext4/xfs/nfs/overlay 等)

缓存可能存在于:

  1. 内核 dentry / inode cache(最常用)
  2. 文件系统自身缓存(如 NFS、FUSE)
  3. 应用层自己缓存结果

二、利用内核已有的缓存(最简单)

1. dentry / inode 缓存(默认就有)

CentOS 默认会缓存目录项:

cat /proc/sys/vm/vfs_cache_pressure
  • 值越小,越倾向于保留 dentry/inode 缓存
  • 默认通常是 100

调优(谨慎):

sysctl -w vm.vfs_cache_pressure=50

⚠ 不建议设为 0,可能导致内存压力


2. 确保目录在 page / slab cache 中

第一次 ls 或 readdir 后,内核会缓存:

ls /path/to/dir   # 预热

重复访问会明显变快。


三、NFS / 网络文件系统缓存(CentOS 常见)

如果是 NFS 目录,readdir 很慢,需要专门缓存。

NFS 属性缓存

mount -o actimeo=600,nocto nfs-server:/dir /mnt

参数说明:

  • actimeo=600:属性和目录缓存 600 秒
  • nocto:减少 close-to-open 一致性检查

查看:

cat /proc/mounts | grep nfs

四、FUSE / OverlayFS 缓存

OverlayFS(Docker 常见)

OverlayFS 的 readdir 性能依赖底层文件系统缓存。

可尝试:

mount -o redirect_dir=on,index=on overlay

五、应用层缓存 readdir(推荐可控方式)

如果你的程序频繁调用 readdir,最可靠的是自己缓存。

示例(C 语言)

#include <dirent.h>
#include <stdlib.h>
#include <string.h>

char **cached_dir(const char *path) {
    DIR *d = opendir(path);
    struct dirent *e;
    char **list = malloc(sizeof(char*) * 1000);
    int n = 0;

    while ((e = readdir(d))) {
        list[n++] = strdup(e->d_name);
    }
    closedir(d);
    list[n] = NULL;
    return list;
}

然后自己控制刷新策略(如 10 秒、文件变更监听)。


六、使用高级库缓存目录

1. fts / nftw(仍无缓存)

只是遍历工具,不缓存。

2. 使用 inotify + 缓存

inotifywait -m /path/to/dir

目录变化时才刷新缓存。


七、CentOS 特有注意点

1. SELinux 可能影响

getenforce

如果是 Enforcing,每次访问可能有策略检查开销。

2. 文件系统选择

  • ext4 / xfs:本地缓存好
  • NFS / Gluster / Ceph:必须显式缓存

八、总结建议

场景 推荐做法
本地目录 依靠内核 dentry 缓存
NFS mount 参数 + actimeo
高频 readdir 应用层缓存
容器 overlay 底层缓存
极致性能 readdir + 自建缓存 + inotify

如果你能说明:

  • 是 C / Python / Shell?
  • 是 本地磁盘还是 NFS?
  • 目录有多大(几万 / 几百万文件)?

我可以给你更具体的缓存方案或代码示例。

0 踩