🗺️ 一张图详解Linux存储堆栈 | 从应用到底层硬件,10层架构全解析!
📖 写在开头:你是不是也这样?
第一段:痛点场景
你有没有遇到过这样的困惑?系统出现存储性能问题,你完全不知道问题出在哪一层。是文件系统的问题?还是LVM的问题?或者是底层驱动的问题?你尝试各种工具排查,但就是找不到问题的根源。
更糟糕的是,当你看到"Linux存储堆栈"这个词时,你只知道它很重要,但完全不知道它到底包含哪些层次,每一层的作用是什么。你尝试阅读文档,但总是被各种术语搞得头晕眼花...
如果你也经历过这种"存储堆栈即天书"的困惑,那么今天FYC要告诉你一个好消息:Linux存储堆栈其实有标准架构图!只要理解了这张图,你就能快速定位存储问题的根源!
今天我们要深入解析的是Thomas-Krenn发布的Linux存储堆栈图(Linux Kernel 6.16版本) ,这是业界最权威、最详细的Linux存储架构图。通过这张图,你将彻底理解数据是如何从应用程序流向物理硬件的。
第二段:本文概述
今天我们要聊的是Linux存储堆栈的完整架构,这是每个运维工程师都必须掌握的基础知识。我们将从Thomas-Krenn发布的权威架构图讲起,带你一步步理解从虚拟文件系统(VFS)到底层硬件驱动的10层架构,以及每一层的功能、工具和故障排除方法。
本文将为你带来:
- 🎯 权威架构图解析:Thomas-Krenn Linux存储堆栈图(Kernel 6.16)完整解读
- 🔧 10层架构详解:从VFS到物理硬件的每一层功能和作用
- ✅ 工具和诊断:每一层对应的诊断工具和故障排除方法
- ⚠️ 关键组件:设备映射器、磁盘调度程序、SCSI中间层等核心组件
- 💡 实战应用:如何利用架构图快速定位存储问题
跟着FYC走,从此告别"存储堆栈即天书"的时代!
第三段:5维度评分表
| 维度 | 评分 | 说明 |
|---|---|---|
| 难度等级 | ⭐⭐⭐⭐ | 需要深入理解存储栈架构和各层功能 |
| 实用价值 | ⭐⭐⭐⭐⭐ | 理解存储栈是排除存储问题的基础 |
| 技术深度 | ⭐⭐⭐⭐ | 从VFS到底层驱动的全面覆盖 |
| 可操作性 | ⭐⭐⭐⭐⭐ | 所有工具和命令都可以直接使用 |
| 紧急性 | ⭐⭐⭐⭐ | 存储问题通常需要快速定位,理解架构是关键 |
📚 正文:干货满满,但要"喂到嘴里"!
🗺️ 一、权威架构图:Thomas-Krenn Linux存储堆栈图
📋 架构图来源和版本
我们今天要解析的是Thomas-Krenn发布的Linux存储堆栈图(Linux Kernel 6.16版本) ,这是业界最权威、最详细的Linux存储架构图。
架构图信息:
-
版本:Linux Kernel 6.16
-
作者:Werner Fischer(Thomas-Krenn知识转移团队成员)
-
许可证:CC-BY-SA 3.0(知识共享署名-相同方式共享3.0)
-
下载地址:
Kernel 6.16的新特性:
根据架构图的更新日志,Kernel 6.16版本包含以下新特性:
- zoned loop block device (zloop) :支持区域循环块设备
- NFS LOCALIO协议:NFS添加LOCALIO协议以获得"极致"性能提升(Kernel 6.12)
- null_blk移除bio-based I/O路径:null_blk设备移除了基于bio的I/O路径(Kernel 6.9)
🎯 架构图的价值
这张架构图的价值在于:
- ✅ 标准化视图:提供了Linux存储栈的标准架构视图
- ✅ 层次清晰:从应用层到底层硬件,每一层都清晰标注
- ✅ 工具对应:每一层都标注了对应的诊断工具
- ✅ 持续更新:随着内核版本更新,架构图也会同步更新
🏗️ 二、Linux存储堆栈10层架构详解
根据Thomas-Krenn架构图和Red Hat官方文档,Linux存储堆栈可以分为10层,从应用程序到底层硬件,每一层都有其特定的功能和作用。
第1层:应用程序层(Application Layer)
功能:
- 应用程序通过POSIX系统调用(如
open()、read()、write()、mmap())访问文件 - 应用程序不需要知道底层文件系统的实现细节
关键特性:
- 标准化的系统调用接口
- 与底层文件系统实现无关
第2层:虚拟文件系统(VFS - Virtual File System)
功能:
- 为读取和写入文件的标准POSIX系统调用提供支持
- 实施通用文件模型,使应用可以使用相同的系统调用访问不同文件系统
- 提供文件系统的通用抽象
关键组件:
- 索引节点缓存(inode cache) :缓存文件元数据
- 目录缓存(dentry cache) :缓存目录条目
- 缓冲区缓存(buffer cache) :与页面缓存统一,用于元数据或原始块I/O
- 页面缓存(page cache) :使用可用内存动态分配,在文件系统读取和写入期间缓存磁盘块
查看VFS内存使用情况:
# 查看简单的缓存概述
free -h
# 查看详细信息
cat /proc/meminfo
# 输出示例:
# MemTotal: 1860624 kB
# MemFree: 1480952 kB
# MemAvailable: 1515816 kB
# Buffers: 2240 kB
# Cached: 164108 kB
# 查看slab信息(inode和dentry缓存)
cat /proc/slabinfo | grep -E "dentry|inode"
清除缓存:
# 清除页面、索引节点和dentry缓存
# 警告:这会导致短期性能下降
echo 3 > /proc/sys/vm/drop_caches
直接I/O(O_DIRECT) :
- 实施自己缓存的应用(如数据库)使用直接I/O来绕过页面缓存
- 使用
O_DIRECT标志的文件会绕过页面缓存 - ⚠️ 注意:多个进程同时使用直接I/O访问同一文件可能导致损坏
第3层:文件系统层(File System Layer)
功能:
- 提供用于组织和命名存储中的元数据和数据的逻辑结构
- 保护数据免受破坏和损坏
文件系统类型:
- 块存储文件系统:XFS、ext4、GFS2、FAT32
- 网络文件系统:NFS、SMB
- 伪文件系统:procfs、sysfs(基于内存)
- 特殊用途文件系统:tmpfs
RHEL默认文件系统:
- RHEL 7及以下:ext4
- RHEL 8及以上:XFS
文件系统特性:
- 与VFS和通用文件模型集成
- 共享基本的POSIX功能
第4层:设备映射器层(Device Mapper Layer)
功能:
- 创建从一个设备层到另一逻辑设备中的块的映射表
- 使用LVM卷、LUKS磁盘加密、RAID和其他兼容层构建复杂的存储结构
关键特性:
- 设备映射器的使用是可选的
- 可以直接使用文件系统格式化物理块设备,而不使用设备映射器
查看设备映射:
# 列出所有设备映射
dmsetup ls
# 输出示例:
# myvg1-mylv1 (252:0)
# 查看设备映射的符号链接
ls -l /dev/mapper/myvg1-mylv1
# 输出:
# lrwxrwxrwx. 1 root root 7 Sep 30 18:30 /dev/mapper/myvg1-mylv1 -> ../dm-0
# 查看设备映射表
dmsetup table /dev/mapper/myvg1-mylv1
# 输出示例:
# 0 1015808 linear 253:17 2048
# 1015808 1015808 linear 253:18 2048
设备映射示例:
假设有一个名为 /dev/mapper/myvg1-mylv1的LVM逻辑卷,它由两个物理卷 /dev/vdb1和 /dev/vdb2构建:
/dev/mapper/myvg1-mylv1 (逻辑设备 /dev/dm-0)
├── 前1015808个块 → /dev/vdb1 (主:次编号 253:17)
└── 后1015808个块 → /dev/vdb2 (主:次编号 253:18)
设备映射器支持的功能:
- LVM:逻辑卷管理
- LUKS:磁盘加密
- MD RAID:软件RAID
- DM Multipath:多路径
- dm-vdo:虚拟数据优化(Kernel 6.9+)
第5层:块层(Block Layer)
功能:
- 提供块设备的统一接口
- 管理I/O请求的排队和调度
关键组件:
- 通用块层(Generic Block Layer) :提供块设备的统一抽象
- I/O调度:管理I/O请求的调度和合并
第6层:磁盘调度程序层(I/O Scheduler Layer)
功能:
- 负责对提交到存储设备的I/O请求进行排序
- 优化I/O性能,减少磁盘寻道时间
RHEL 8的变化:
- 仅支持多队列调度:RHEL 8中,块设备仅支持多队列调度
- 传统单队列调度程序已删除:RHEL 7及更早版本中的传统单队列调度程序已被删除
可用的多队列调度程序:
# 查看可用的调度程序
cat /sys/block/sda/queue/scheduler
# 输出示例:
# [mq-deadline] kyber bfq none
调度程序类型:
-
mq-deadline:
- 将排队的I/O请求分类为读取或写入批处理
- 按逻辑块寻址(LBA)递增顺序进行调度
- 特别适用于读取操作比写入操作更频繁的情况
-
kyber:
- 通过计算提交到块I/O层的每个I/O请求的延迟,对自身进行调优
- 实现延迟目标
-
bfq:
- 确保单个应用不会占用所有带宽
- 专注于提供最低延迟,而不是实现最大的吞吐量
-
none:
- 实施先进先出(FIFO)调度算法
- 通过简单的上次点击缓存在通用块层合并请求
查看当前调度程序:
# 查看指定设备的调度程序
cat /sys/block/sda/queue/scheduler
# 方括号[]中的是当前活动的调度程序
# 查看所有块设备的调度程序
for dev in /sys/block/sd*/queue/scheduler; do
echo "$dev: $(cat $dev)"
done
更改调度程序:
# 更改调度程序(例如:改为kyber)
echo kyber > /sys/block/sda/queue/scheduler
# 永久更改(需要修改udev规则或启动脚本)
第7层:设备映射器多路径层(DM Multipath Layer)
功能:
- 在服务器和存储阵列之间配置多个I/O路径
- 使多个路径显示为单个设备
- 提供冗余和负载均衡
多路径配置:
服务器
├── HBA 1 → 路径1 → 存储控制器1
├── HBA 1 → 路径2 → 存储控制器2
├── HBA 2 → 路径3 → 存储控制器1
└── HBA 2 → 路径4 → 存储控制器2
↓
多路径设备(mpath)
多路径设备命名:
- WWID:存储设备的全球ID
- mpath + 序列号:如
mpath0、mpath1 - 自定义名称:通过配置文件自定义
多路径管理工具:
# 查看多路径设备
multipath -ll
# 查看多路径状态
multipathd show paths
# 重新加载多路径配置
multipathd reload
第8层:SCSI中间层(SCSI Mid-Layer)
功能:
- 提供存储设备的SCSI目标和与存储设备通信的主机总线适配器(HBA)或硬件接口卡驱动程序之间的网桥
- 所有可以使用或模拟SCSI协议的设备都可以使用SCSI中间层
SCSI设备类型:
- SCSI磁盘(sd) :
/dev/sda、/dev/sdb等 - SCSI CDROM(sr) :
/dev/sr0等 - SCSI磁带(st) :基于字符的磁带设备
- 通用SCSI设备(sg) :扫描仪等通用SCSI设备
支持的设备类型:
- SATA设备:通过libata驱动,显示为SCSI设备
- USB存储:显示为SCSI设备
- 虚拟机磁盘:显示为SCSI设备
- iSCSI设备:使用TCP/IP传输,使用SCSI驱动程序(如
iscsi_tcp)
绕过SCSI中间层的设备:
- virtio_blk:超虚拟化设备,不模拟SCSI协议
- 直接与块层的调度程序交互
查看SCSI设备:
# 查看SCSI设备
lsscsi
# 查看SCSI设备详细信息
cat /proc/scsi/scsi
# 查看SCSI设备属性
udevadm info /dev/sda
第9层:低级驱动程序层(Low-Level Driver Layer)
功能:
- 与物理系统硬件通信
- 从块层的调度程序接收I/O,并将其分派到存储硬件
驱动程序类型:
-
SCSI HBA驱动程序:
- Qlogic:
qla2xxx - Adaptec:
aacraid - Emulex:
lpfc
- Qlogic:
-
本地存储驱动程序:
- SATA:
libata、ahci - USB:
libata、ahci
- SATA:
-
网络存储驱动程序:
- iSCSI:
iscsi_tcp(在传递到网络堆栈之前使用SCSI驱动程序)
- iSCSI:
-
虚拟化驱动程序:
virtio_scsi:SCSI磁盘设备vmw_pvscsi:VMware SCSI设备virtio_blk:直接与块层调度程序交互
驱动程序特性:
- 驱动程序不会将I/O排入队列
- 驱动程序会跟踪活动的I/O请求
- 控制器接受传入的I/O请求并将它们转发到底层硬件控制器
查看驱动程序:
# 查看加载的存储驱动程序
lsmod | grep -E "qla|aac|lpfc|ahci|virtio"
# 查看设备对应的驱动程序
udevadm info /dev/sda | grep DRIVER
# 查看驱动程序信息
modinfo qla2xxx
第10层:物理硬件层(Physical Hardware Layer)
功能:
- 实际的存储硬件设备
- 包括HDD、SSD、NVMe设备等
硬件类型:
-
传统存储:
- HDD(机械硬盘)
- SSD(固态硬盘)
-
高性能存储:
- NVMe设备
- NVMe over Fabrics
-
网络存储:
- iSCSI存储
- Fibre Channel存储
查看硬件信息:
# 查看块设备信息
lsblk
# 查看设备详细信息
smartctl -a /dev/sda
# 查看NVMe设备信息
nvme list
nvme id-ctrl /dev/nvme0
🔧 三、Stratis存储管理:现代化的存储管理方案
📋 Stratis简介
Stratis是Red Hat提供的简化本地存储管理的解决方案,注重简单性。该服务管理从一个或多个本地磁盘或分区创建的物理存储设备池。
🎯 Stratis特性
- 存储池管理:从多个块设备创建存储池
- 精简配置:卷从池创建,具有精简配置功能
- 文件系统快照:支持文件系统快照
- 数据分层:支持数据分层
支持的块设备类型:
- LUKS(加密设备)
- LVM逻辑卷
- MD RAID
- DM多路径
- iSCSI
- HDD和SSD
- NVMe设备
🔧 Stratis安装和配置
安装Stratis:
# 安装Stratis软件包
yum install stratisd stratis-cli
# 启用并启动Stratis服务
systemctl enable --now stratisd
准备块设备:
# 擦除块设备上的任何现有文件系统、分区表或RAID签名
wipefs --all /dev/sdb
wipefs --all /dev/sdc
创建Stratis池:
# 创建Stratis池
stratis pool create my-pool /dev/sdb
# 将更多块设备附加到池
stratis pool add-data my-pool /dev/sdc
创建Stratis文件系统:
# 在池上创建Stratis文件系统
stratis fs create my-pool my-fs
# 查看Stratis文件系统UUID(用于/etc/fstab)
lsblk --output=UUID /dev/stratis/my-pool/my-fs
# 输出示例:
# UUID
# b65883bf-cd83-420d-bb78-433b6545c053
挂载Stratis文件系统:
# 临时挂载
mount /dev/stratis/my-pool/my-fs /mnt
# 永久挂载(在/etc/fstab中添加)
UUID=b65883bf-cd83-420d-bb78-433b6545c053 /mnt xfs defaults,x-systemd.requires=stratisd.service 0 0
💡 Stratis vs 传统LVM
Stratis的优势:
- ✅ 简单易用:命令行接口更简单
- ✅ 自动化管理:自动处理文件系统扩展
- ✅ 集成快照:文件系统快照功能集成
传统LVM的优势:
- ✅ 更灵活:更多的配置选项
- ✅ 更成熟:更广泛的使用和文档
- ✅ 更多工具:更多的管理和诊断工具
📊 四、存储堆栈故障排除:按层诊断
理解存储堆栈的每一层后,我们可以按照层次进行故障排除:
第1步:确定问题所在的层
# 1. 检查应用程序层
# 查看应用程序的错误日志
journalctl -u <application-service>
# 2. 检查VFS层
# 查看内存使用情况
free -h
cat /proc/meminfo
# 3. 检查文件系统层
# 查看文件系统状态
df -h
mount | grep -E "xfs|ext4"
# 4. 检查设备映射器层
dmsetup ls
dmsetup status
# 5. 检查块层和调度程序
cat /sys/block/sda/queue/scheduler
iostat -x 1
# 6. 检查多路径层
multipath -ll
multipathd show paths
# 7. 检查SCSI中间层
lsscsi
cat /proc/scsi/scsi
# 8. 检查低级驱动程序
lsmod | grep -E "qla|aac|lpfc|ahci|virtio"
dmesg | grep -i "error|fail"
# 9. 检查物理硬件
smartctl -a /dev/sda
nvme list
第2步:使用对应的诊断工具
VFS层诊断:
# 查看页面缓存使用情况
cat /proc/meminfo | grep -E "Cached|Buffers"
# 查看inode和dentry缓存
cat /proc/slabinfo | grep -E "dentry|inode"
文件系统层诊断:
# 检查文件系统错误
xfs_repair -n /dev/sda1 # XFS(仅检查,不修复)
fsck -n /dev/sda1 # ext4(仅检查,不修复)
# 查看文件系统统计信息
xfs_info /dev/sda1 # XFS
tune2fs -l /dev/sda1 # ext4
设备映射器层诊断:
# 查看设备映射表
dmsetup table
dmsetup status
# 查看LVM信息
pvs
vgs
lvs
I/O调度程序诊断:
# 查看I/O统计信息
iostat -x 1
# 查看I/O等待时间
iotop
# 查看块设备统计信息
cat /proc/diskstats
多路径诊断:
# 查看多路径状态
multipath -ll
multipathd show paths format "%d %s %t %T %o"
# 查看多路径配置
cat /etc/multipath.conf
SCSI层诊断:
# 查看SCSI设备
lsscsi -v
# 查看SCSI错误
dmesg | grep -i scsi
# 查看SCSI设备属性
udevadm info /dev/sda
硬件层诊断:
# 查看SMART信息
smartctl -a /dev/sda
# 查看NVMe设备信息
nvme list
nvme smart-log /dev/nvme0
# 查看硬件错误
dmesg | grep -i "error|fail"
🎁 写在结尾!
📋 价值总结
今天FYC为你带来了Linux存储堆栈的完整解析:
✅ 权威架构图:
- Thomas-Krenn发布的Linux存储堆栈图(Kernel 6.16)
- 业界最权威、最详细的Linux存储架构图
- 持续更新,跟随内核版本
✅ 10层架构详解:
- 从应用程序层到物理硬件层的完整解析
- 每一层的功能、工具和诊断方法
- VFS、文件系统、设备映射器、调度程序等关键组件
✅ 关键组件:
- VFS:虚拟文件系统,提供统一接口和缓存
- 设备映射器:LVM、LUKS、RAID、多路径
- 磁盘调度程序:mq-deadline、kyber、bfq、none
- SCSI中间层:统一SCSI设备接口
- 低级驱动程序:HBA、SATA、USB、虚拟化驱动
✅ 故障排除方法:
- 按层诊断的方法
- 每一层对应的诊断工具
- 从应用到底层的完整排查流程
掌握了Linux存储堆栈的完整架构,你就能在存储问题发生时快速定位问题所在的层次,使用对应的工具进行诊断和修复!
🎯 行动号召
觉得这篇文章还不够过瘾?想要看到更详细的存储堆栈图解析、各层故障排除案例、以及性能优化方法吗?
👉 公众号【源宇宙十三站】 ,即可获取:
- 📚 Linux存储堆栈图高清PDF(Kernel 6.16版本)
- 🔧 存储堆栈故障排除脚本(按层自动诊断)
- 📊 存储性能分析工具集(iostat、iotop、blktrace等)
- 💡 各层故障排除案例解析(真实生产环境场景)
- 🎯 存储性能优化指南(调度程序调优、缓存优化等)
FYC的使命:让每个运维工程师都能成为存储故障诊断专家!技术要硬核,文案要上头!🔥
📚 参考资料
- Thomas-Krenn Linux Storage Stack Diagram
- Linux Storage Stack Diagram v6.16 PDF
- Red Hat Enterprise Linux 8 Storage Administration Guide
- Linux Kernel 6.16 Release Notes
#运维 #Linux #存储堆栈 #VFS #文件系统 #LVM #故障排除 #RCA #根因分析 #技术干货 #RedHat #RHEL #ThomasKrenn