Linux存储系统原理解析_数据读写流程说明【教程】

10次阅读

VFS 层将 write()系统调用统一转为对 inode 和 page cache 的操作,屏蔽文件系统差异;数据仅在调用 fsync()/sync()后才落盘,否则停留于内存脏页,由 writeback 线程按 dirty_ratio 阈值异步刷回。

Linux 存储系统原理解析_数据读写流程说明【教程】

数据写入时,VFS 层到底做了什么

Linux 写操作不会直接触达磁盘,而是先经过 VFS(Virtual File System)抽象层。它把 write() 系统调用统一转成对 inode 和 page cache 的操作,屏蔽了 ext4、XFS、Btrfs 等具体文件系统的差异。

关键点在于:只要没显式调用 fsync()sync(),数据就只停留在内存的 page cache 中,尚未落盘。

  • write() 返回成功 ≠ 数据已写入磁盘
  • 脏页(dirty page)由内核线程 pdflush(旧内核)或 writeback(4.0+)异步刷回
  • /proc/sys/vm/dirty_ratio/proc/sys/vm/dirty_background_ratio 控制刷盘触发阈值

ext4 文件系统如何分配磁盘块

ext4 使用 extent(连续块描述)替代早期 ext2/3 的间接块指针,在大文件场景下显著减少元数据开销。一个文件的物理布局由 inode 中的 i_block[] 数组 + extent tree 共同描述。

当需要新块时,ext4 优先在同一个 block group 内分配,以提升局部性;若空间不足,则触发跨 group 搜索,并可能触发 lazy initialization(如未格式化的 block group 被跳过初始化)。

  • 每个 block group 包含自己的 bitmap、inode table 和 data blocks,避免全局锁争用
  • 使用 chattr +e 可强制启用 extent 模式(新建文件默认已启用)
  • 碎片严重时,e2fsck -D 可重建目录索引,但不整理文件数据块

从 write() 到磁盘扇区:IO 逐层穿透

用户态 write() 发起后,路径为:libc → syscall → VFS → filesystem (ext4) → block layer → device driver → disk firmware。其中 block layer 是关键枢纽,负责 IO 合并、排序、限速和队列调度。

常见误区是认为“写得快 = 磁盘快”,其实瓶颈常卡在 block layer 的 queue depth 或 scheduler 策略上:

  • SSD 推荐用 nonemq-deadline 调度器,避免传统电梯算法引入额外延迟
  • cat /sys/block/sda/queue/scheduler 查看当前调度器,echo mq-deadline > /sys/block/sda/queue/scheduler 可临时切换
  • NVMe 设备默认使用 none(即 bypass scheduler),但部分老内核需手动设置
echo 'vm.dirty_ratio = 30' >> /etc/sysctl.conf echo 'vm.dirty_background_ratio = 5' >> /etc/sysctl.conf sysctl -p

读取时 page cache 命中与绕过的条件

read() 默认走 page cache 路径:先查该文件对应 offset 是否已在内存中;命中则直接拷贝,不发磁盘 IO。但以下情况会绕过 cache:

  • 打开文件时指定 O_DIRECT 标志,要求 kernel bypass page cache,直接与设备驱动交互
  • 使用 posix_fadvise(fd, offset, len, POSIX_FADV_DONTNEED) 主动丢弃缓存页
  • 内存紧张时,kernel 可能回收 clean page(未修改的缓存页),下次读仍需 IO

O_DIRECT 要求用户缓冲区地址、偏移、长度均按 logical_block_size 对齐(通常是 512B 或 4K),否则 write() 返回 -EINVAL

实际调试时,strace -e trace=write,read,fsyncblktrace -d /dev/sda 能清晰区分是应用层逻辑问题,还是底层 IO 调度或硬件响应慢。page cache 的存在让“读写快”变得廉价,但也让“数据持久性”变成需要主动管理的事。

text=ZqhQzanResources