Linux故障诊断系列3-存储专题-3.1-一张图详解Linux存储堆栈

52 阅读16分钟

🗺️ 一张图详解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存储架构图。

架构图信息

  • 来源Thomas-Krenn Wiki

  • 版本: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系统调用提供支持
  • 实施通用文件模型,使应用可以使用相同的系统调用访问不同文件系统
  • 提供文件系统的通用抽象

关键组件

  1. 索引节点缓存(inode cache) :缓存文件元数据
  2. 目录缓存(dentry cache) :缓存目录条目
  3. 缓冲区缓存(buffer cache) :与页面缓存统一,用于元数据或原始块I/O
  4. 页面缓存(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)

功能

  • 提供用于组织和命名存储中的元数据和数据的逻辑结构
  • 保护数据免受破坏和损坏

文件系统类型

  1. 块存储文件系统:XFS、ext4、GFS2、FAT32
  2. 网络文件系统:NFS、SMB
  3. 伪文件系统:procfs、sysfs(基于内存)
  4. 特殊用途文件系统: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请求的排队和调度

关键组件

  1. 通用块层(Generic Block Layer) :提供块设备的统一抽象
  2. 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

调度程序类型

  1. mq-deadline

    • 将排队的I/O请求分类为读取或写入批处理
    • 按逻辑块寻址(LBA)递增顺序进行调度
    • 特别适用于读取操作比写入操作更频繁的情况
  2. kyber

    • 通过计算提交到块I/O层的每个I/O请求的延迟,对自身进行调优
    • 实现延迟目标
  3. bfq

    • 确保单个应用不会占用所有带宽
    • 专注于提供最低延迟,而不是实现最大的吞吐量
  4. 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 + 序列号:如 mpath0mpath1
  • 自定义名称:通过配置文件自定义

多路径管理工具

# 查看多路径设备
multipath -ll

# 查看多路径状态
multipathd show paths

# 重新加载多路径配置
multipathd reload
第8层:SCSI中间层(SCSI Mid-Layer)

功能

  • 提供存储设备的SCSI目标和与存储设备通信的主机总线适配器(HBA)或硬件接口卡驱动程序之间的网桥
  • 所有可以使用或模拟SCSI协议的设备都可以使用SCSI中间层

SCSI设备类型

  1. SCSI磁盘(sd)/dev/sda/dev/sdb
  2. SCSI CDROM(sr)/dev/sr0
  3. SCSI磁带(st) :基于字符的磁带设备
  4. 通用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,并将其分派到存储硬件

驱动程序类型

  1. SCSI HBA驱动程序

    • Qlogic:qla2xxx
    • Adaptec:aacraid
    • Emulex:lpfc
  2. 本地存储驱动程序

    • SATA:libataahci
    • USB:libataahci
  3. 网络存储驱动程序

    • iSCSI:iscsi_tcp(在传递到网络堆栈之前使用SCSI驱动程序)
  4. 虚拟化驱动程序

    • 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设备等

硬件类型

  1. 传统存储

    • HDD(机械硬盘)
    • SSD(固态硬盘)
  2. 高性能存储

    • NVMe设备
    • NVMe over Fabrics
  3. 网络存储

    • 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的使命:让每个运维工程师都能成为存储故障诊断专家!技术要硬核,文案要上头!🔥


📚 参考资料


#运维 #Linux #存储堆栈 #VFS #文件系统 #LVM #故障排除 #RCA #根因分析 #技术干货 #RedHat #RHEL #ThomasKrenn