Linux 通过 VFS 层抽象不同文件系统的实现:
应用层
↓
系统调用(open, read, write, close)
↓
VFS 层(统一接口)
↓
具体文件系统(ext4, xfs, btrfs 等)
↓
块设备层
↓
硬件驱动
- inode(索引节点):存储文件元数据(权限、大小、时间戳、数据块指针等)
- dentry(目录项):文件名与 inode 的映射关系
- file(文件对象):进程打开文件的实例
- Block 大小:通常 4KB
- inode 结构:直接块(12个)+ 间接块 + 二级间接块 + 三级间接块
- 日志(Journal):保证文件系统一致性,支持数据、元数据或混合模式
- 延迟分配:推迟块分配时机,提升性能
- 多块分配:一次分配多个连续块,减少碎片
- 标准 IO:带缓冲,用户态缓存 + 内核页缓存
- 直接 IO(Direct IO):绕过页缓存,直接读写磁盘
- 内存映射 IO(mmap):将文件映射到进程地址空间
- 异步 IO(AIO):非阻塞 IO,提交请求后立即返回
- 内核使用空闲内存缓存磁盘数据
- 读操作:优先从页缓存读取
- 写操作:写入页缓存,后台同步到磁盘
- 脏页(Dirty Page):被修改但未同步的页缓存
# 文件系统信息
df -h # 查看磁盘使用情况
df -i # 查看 inode 使用情况
mount # 查看挂载点
lsblk # 列出块设备
# 文件操作
stat file.txt # 查看文件详细信息
ls -li # 显示 inode 号
du -sh /path # 查看目录大小
find / -size +100M # 查找大文件
# 磁盘 IO 监控
iostat -x 1 # 监控磁盘 IO 性能
iotop # 实时查看进程 IO 使用
dstat -d # 综合监控工具
# 文件系统检查与修复
fsck /dev/sda1 # 检查并修复文件系统
tune2fs -l /dev/sda1 # 查看文件系统参数
# 页缓存管理
sync # 同步脏页到磁盘
echo 3 > /proc/sys/vm/drop_caches # 清理页缓存package main
import (
"net"
"os"
"syscall"
)
// ZeroCopyFileSend 使用 sendfile 实现零拷贝文件传输
func ZeroCopyFileSend(conn *net.TCPConn, filePath string) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
return err
}
// 获取文件描述符
filefd := int(file.Fd())
// 获取 socket 文件描述符
connFile, err := conn.File()
if err != nil {
return err
}
defer connFile.Close()
sockfd := int(connFile.Fd())
// 使用 sendfile 系统调用实现零拷贝
var offset int64 = 0
remaining := fileInfo.Size()
for remaining > 0 {
// Linux sendfile: 从文件直接发送到 socket
n, err := syscall.Sendfile(sockfd, filefd, &offset, int(remaining))
if err != nil {
return err
}
remaining -= int64(n)
}
return nil
}零拷贝原理:
- 传统方式:文件 → 内核缓冲区 → 用户缓冲区 → Socket缓冲区 → 网卡(4次拷贝)
- 零拷贝:文件 → Socket缓冲区 → 网卡(2次拷贝,无用户态参与)
现象:磁盘空间充足但无法创建文件
原因:大量小文件导致 inode 用尽
查看:
df -i # 查看inode使用率解决:
- 删除不必要的小文件
- 重新格式化分区增加 inode 数量
1. 使用 SSD:IOPS 和延迟优于机械硬盘
2. 合理选择 IO 模式:
- 数据库:Direct IO + AIO
- 日志文件:标准 IO + 批量写入
- 大文件传输:mmap 或 sendfile
3. IO 调度器选择:
# 查看当前调度器
cat /sys/block/sda/queue/scheduler
# SSD 推荐 noop 或 deadline
echo noop > /sys/block/sda/queue/scheduler
# 机械硬盘推荐 cfq(默认)查看当前限制:
ulimit -n # 当前shell的限制
cat /proc/sys/fs/file-max # 系统级限制调整限制:
# 临时修改
ulimit -n 65535
# 永久修改 /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535生产环境建议:
- Web服务器:65535
- 数据库:100000+
文件系统是操作系统管理存储资源的核心组件,理解VFS、inode、页缓存等概念对于优化IO性能至关重要。
关键要点:
- ✅ VFS提供统一的文件操作接口
- ✅ inode存储文件元数据,与文件名分离
- ✅ 页缓存可显著提升IO性能
- ✅ 零拷贝技术减少数据拷贝次数
💡 思考题:
- VFS的作用是什么?为什么需要它?
- inode耗尽和磁盘空间耗尽有什么区别?
- 什么场景下应该使用Direct IO?