在 CentOS 上加速 readdir()(目录遍历),通常并不是“改一行代码”的问题,而是 系统层面 + 文件系统层面 + 使用方式 的综合优化。下面按 实用程度 给你一个完整清单。
不要盲目优化,先确认是 CPU / IO / 元数据 / 缓存 问题:
# 查看系统负载
top
iostat -x 1
vmstat 1
# 查看目录大小
ls -l | wc -l
find . -maxdepth 1 | wc -l
如果:
iostat 显示 %util 很高 → 磁盘 IO 瓶颈cache 命中低 → 目录项未缓存很多慢的根本原因是:
一个目录里几万~几百万文件
这是 ext4 / xfs 的已知性能杀手。
✅ 正确做法:
bad:
/data/files/1.jpg
/data/files/2.jpg
good:
/data/files/00/1.jpg
/data/files/01/2.jpg
或按时间:
/data/2026/01/21/xxx
✅ 收益:至少 5~10 倍提升
openat + getdents(最底层)readdir() 是 glibc 封装,底层是 getdents。
如果你在 C/C++,直接调用 getdents 会比 readdir() 快。
#include <fcntl.h>
#include <sys/syscall.h>
#include <linux/dirent.h>
如果做不到,至少:
DIR *dir = opendir(path);
int fd = dirfd(dir);
减少路径解析。
statx / stat 缓存(减少系统调用)常见错误:
while (readdir()) {
stat(); // ❌ 每个文件一次 stat
}
✅ 改进:
lstat() → 合并逻辑
CentOS 7/8 默认推荐 XFS。
检查:
df -T
如果是 ext4,考虑迁移到 XFS(新分区)。
编辑 /etc/fstab:
defaults,noatime,nodiratime
例如:
/dev/sdb1 /data xfs defaults,noatime,nodiratime 0 0
✅ 减少元数据写入
# 查看
cat /proc/sys/vm/vfs_cache_pressure
# 降低(优先缓存目录)
sysctl -w vm.vfs_cache_pressure=50
永久:
echo "vm.vfs_cache_pressure = 50" >> /etc/sysctl.conf
ls / find(非常慢)❌ 慢:
ls -l
find .
✅ 快:
ls # 不要 -l
如果是代码:
readdir() + 缓存第一次扫描后缓存结果(Redis / 内存):
第一次:readdir → cache
后续:直接读 cache
io_uring(高级)Linux 5.1+ 支持 io_uring,可异步读取目录。
适合:
示例(高级,不展开):
io_uring_prep_getdents| 场景 | 推荐方案 |
|---|---|
| 目录 < 1 万文件 | 基本不用优化 |
| 目录 10 万+ | 拆分目录 |
| 磁盘 IO 高 | XFS + noatime |
| 频繁 readdir | 缓存结果 |
| C/C++ 程序 | getdents |
| Web 文件服务 | hash 目录结构 |
readdir 慢,90% 不是 readdir 的问题,而是“目录设计 + 缓存 + 文件系统”的问题。
如果你愿意,可以告诉我:
我可以直接给你 针对性的优化方案或示例代码。