在 CentOS 上 readdir() 或 ls 等目录遍历操作“慢”,通常不是单一原因,而是 文件系统、缓存、挂载参数、目录规模、SELinux、网络存储 等多种因素叠加。下面按常见原因由高到低给你一个系统性的排查思路。
如果目录里有 几十万 / 上百万个文件:
ls /some/dir # 会非常慢
原因:
readdir() 需要线性遍历目录项ls 默认会 stat() 每个文件(更慢)✅ 验证:
ls -1 | wc -l
✅ 优化:
ls -f(不排序、不 stat)ls -f /some/dir
第一次访问慢,第二次快,通常是缓存问题。
✅ 验证:
# 第一次
time ls /bigdir
# 清缓存(测试用)
sync; echo 3 > /proc/sys/vm/drop_caches
# 再测
time ls /bigdir
✅ 说明:
✅ 优化:
stat() 放大问题(ls 默认行为)readdir() 本身只返回文件名,但:
ls
ls -l
会触发 大量 stat() 系统调用,非常慢。
✅ 验证:
strace ls -l /bigdir 2>&1 | grep stat
✅ 优化:
ls -ffind /dir -maxdepth 1readdir(),不要 lstat()mount | grep ext4
常见影响参数:
dir_index(默认开启,没开会慢)noatime 没开(每次访问都写 atime)✅ 建议:
mount -o remount,noatime,nodiratime /mountpoint
长期大量小文件、反复删除创建,会导致目录元数据碎片化。
✅ 检查:
filefrag -v /some/dir
✅ 解决:
如果是:
ls /mnt/nfs
那 readdir() 慢是正常现象。
原因:
ls -l 会触发大量 GETATTR✅ 优化:
mount -o nocto,noatime,actimeo=60
或避免对 NFS 目录做 ls -l
尤其在:
✅ 验证:
getenforce
setenforce 0 # 临时关闭测试
✅ 若明显变快:
systemctl status auditd
如果规则很多,readdir / open 都会被记录。
✅ 验证:
auditctl -l
如果你在 C / C++ / Python 里用 readdir() 慢:
✅ 对比:
strace -c ./your_program
常见错误:
✅ 优化:
getdents()(更底层)你可以按顺序执行:
# 1. 目录文件数量
ls -1 | wc -l
# 2. 是否冷缓存
cat /proc/sys/vm/drop_caches
# 3. 是否 NFS
mount | grep nfs
# 4. ls -f 是否快很多
time ls -f /dir
# 5. SELinux
getenforce
CentOS 上 readdir 慢,90% 是“目录太大 + stat + 缓存未命中 + NFS”的组合问题。
如果你愿意,可以告诉我:
ls -f 是否快我可以直接给你 针对性的优化方案(甚至改挂载参数或代码)。