在 CentOS 上遇到 readdir() 很慢,通常不是单一原因,而是 文件系统、目录结构、系统配置、应用行为 共同作用的结果。下面按常见原因由高到低给你系统梳理。
readdir() 本质上是遍历目录项:
✅ 验证方式:
ls -1 | wc -l
✅ 为什么慢:
✅ 解决建议:
a/ab/abc.txt
readdir() 依赖:
如果:
会导致大量磁盘 IO。
✅ 验证:
free -h # 看 cached
vmstat 1
iostat -x 1
✅ 解决:
ls dir > /dev/null
dir_index(bitmap + HTree)检查:
mount | grep ext4
优化建议:
mount -o noatime,nodiratime,data=writeback
⚠️ 仅测试环境,生产慎用
inode64 没开,可能 IO 偏高mount | grep xfs
如果是 NFS / CIFS / GlusterFS / CephFS:
readdir() 会 非常慢,因为:
✅ 验证:
df -hT
✅ 解决:
readdir() 大目录SELinux 会对目录访问做安全检查。
✅ 验证:
getenforce
临时测试:
setenforce 0
如果明显变快,则说明 SELinux 是原因之一。
✅ 建议:
stat() 被隐式调用(glibc 行为)很多程序在使用 readdir() 后 又调用 stat() / lstat():
while ((entry = readdir(dir))) {
stat(entry->d_name, &st);
}
这会成倍放大 IO。
✅ 解决:
getdents()readdir() + dirfd() + fstatat()readdir() 缓冲策略readdir() 实际是:
getdents()在老版本 glibc 上,大目录性能更差。
✅ 检查:
ldd --version
uname -r
✅ 解决建议:
机械盘 + 大目录 = 灾难
✅ 检查:
iostat -x 1
✅ 解决:
| 场景 | 优化 |
|---|---|
| 单目录百万文件 | 拆分目录 |
| NFS | 避免直接 readdir |
| 冷目录 | 预热 |
| 应用层 | 避免 stat |
| 老系统 | 升级 kernel / glibc |
| SELinux | 优化 policy |
如果你愿意,我可以帮你:
你可以直接贴:
ls -1 | wc -l
df -hT
mount