将 RAID、Btrfs 和 LVM Cache 这三者组合,本质上是在打造一个融合了极致性能、数据安全与灵活管理的企业级存储架构。它并非一项简单的操作,但其带来的强大功能,使其在特定场景下成为值得考虑的解决方案。它的平衡点相对偏向高级用户和企业环境,它虽然功能非常强大,但同时也带来了显著的复杂性和数据一致性的风险。是否采用这套方案,关键在于判断其是否能带来独特的业务价值。
下面为您编写一套完整的命令,用于从零创建与您当前系统架构一致的存储方案:mdadm RAID1(HDD)+ mdadm RAID0(NVMe)+ LVM + lvmcache + Btrfs。
⚠️ 警告:以下命令会清空指定磁盘上的所有数据。请务必备份重要数据,并确认磁盘设备名称无误。
架构预览
- 两块 HDD:
/dev/sdb、/dev/sdc→ RAID1 →md1 - 两块 NVMe:
/dev/nvme0n1、/dev/nvme0n2→ RAID0 →md2 - 用
md2(SSD RAID0)作为md1(HDD RAID1)的缓存(lvmcache) - 在缓存的 LVM 逻辑卷上创建 Btrfs 文件系统
- sda为系统盘

1. 准备磁盘(分区)
虽然可以直接使用整个磁盘,但推荐创建分区(便于标识)。使用 parted 或 fdisk 创建 GPT 分区表和单一分区。
# 以 /dev/sda 为例,对 /dev/sdb、/dev/nvme0n1、/dev/nvme1n1 重复操作
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart primary 0% 100%
sudo parted /dev/sdc --script mklabel gpt
sudo parted /dev/sdc --script mkpart primary 0% 100%
sudo parted /dev/nvme0n1 --script mklabel gpt
sudo parted /dev/nvme0n1 --script mkpart primary 0% 100%
sudo parted /dev/nvme0n2 --script mklabel gpt
sudo parted /dev/nvme0n2 --script mkpart primary 0% 100%
# 可选:标记为 RAID 标志
sudo parted /dev/sdb --script set 1 raid on
sudo parted /dev/sdc --script set 1 raid on
sudo parted /dev/nvme0n1 --script set 1 raid on
sudo parted /dev/nvme0n2 --script set 1 raid on
# 刷新分区表
sudo partprobe /dev/sdb
确保分区后设备名为 /dev/sdb1、/dev/sdc1、/dev/nvme0n1p1、/dev/nvme0n2p1。

2. 创建 mdadm RAID 阵列
# 安装 mdadm(如未安装)
sudo apt update && sudo apt install -y mdadm
# 创建 RAID1(HDD)
sudo mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1
# 创建 RAID0(NVMe)
sudo mdadm --create /dev/md2 --level=0 --raid-devices=2 /dev/nvme0n1p1 /dev/nvme0n2p1
# 查看阵列状态
cat /proc/mdstat
# 保存 RAID 配置
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u


3. 创建 LVM 物理卷、卷组和逻辑卷
# 安装 lvm2(如未安装)
sudo apt install -y lvm2
# 在两个 RAID 设备上创建物理卷
sudo pvcreate /dev/md1 /dev/md2
# 创建卷组(统一管理)
sudo vgcreate vg_storage /dev/md1 /dev/md2
# 查看卷组
sudo vgs

4. 设置 lvmcache(用 RAID0 加速 RAID1)
4.1 创建主逻辑卷(位于 HDD RAID1 上)
# 使用 md1 上的全部空间创建主 LV,命名为 lv_data
sudo lvcreate -n lv_data -l 100%PVS vg_storage /dev/md1

4.2 创建缓存池(位于 SSD RAID0 上)
# 创建缓存数据卷和缓存元数据卷
# 通常缓存数据卷占用 SSD 大部分空间,元数据卷约 1/1000 数据卷大小
sudo lvcreate -n cache_meta -L 1G vg_storage /dev/md2 # 根据 SSD 大小调整
sudo lvcreate -n cache_data -l 90%PVS vg_storage /dev/md2
# 将两者组合成缓存池
sudo lvconvert --type cache-pool --poolmetadata vg_storage/cache_meta vg_storage/cache_data

4.3 将缓存池附加到主逻辑卷
sudo lvconvert --type cache --cachepool vg_storage/cache_data vg_storage/lv_data
# 或者新版 LVM 语法:
# sudo lvconvert --type cache --cachepool vg_storage/cache_data vg_storage/lv_data

检查状态:
sudo lvs -a -o name,attr,size,pool_lv

5. 在缓存的逻辑卷上创建 Btrfs 文件系统
# 安装 btrfs-progs
sudo apt install -y btrfs-progs
# 格式化(这里使用默认的 single 数据 profile,可指定 metadata 为 raid1 等)
sudo mkfs.btrfs -L pool1 /dev/vg_storage/lv_data
# 若需要挂载选项(如启用压缩),可稍后在 fstab 中配置

6. 挂载文件系统
# 创建挂载点
sudo mkdir -p /volume1 /home
# 临时挂载
sudo mount /dev/vg_storage/lv_data /volume1
sudo mkdir /storage
sudo mount --bind /volume1 /storage # 若需要与您系统一致
# 永久挂载:编辑 /etc/fstab
echo "UUID=$(sudo blkid -s UUID -o value /dev/vg_storage/lv_data) /volume1 btrfs defaults,compress=zstd 0 0" | sudo tee -a /etc/fstab
7. 验证最终架构
lsblk --fs
cat /proc/mdstat
sudo btrfs filesystem show /volume1
sudo lvs -a

您将看到类似您原始输出的层次结构:

8.说明与注意事项
- 缓存模式:默认是
writethrough(写入同时写 HDD 和 SSD,安全但 SSD 写入压力大)。如需writeback(先写 SSD 后回写 HDD,性能更高但有数据风险),可在附加缓存后执行:
sudo lvchange --cachemode writeback vg_storage/lv_data
- 调整缓存大小:若未来需要更换 SSD 或增加容量,需先分离缓存池(
lvconvert --splitcache),调整后再重新附加。 - RAID0 安全性:NVMe RAID0 无冗余,一块坏掉缓存失效,但主数据仍安全(位于 HDD RAID1 上)。建议对 Btrfs 定期快照并发送至另一存储。
- Btrfs 特性:由于底层是单设备 LVM 卷,Btrfs 的“自动修复”依赖 DUP 或 RAID profile,建议在格式化时指定:
sudo mkfs.btrfs -m dup -d single /dev/vg_storage/lv_data
以增强元数据保护。
9.命令详解
lsblk 是一个用于列出系统上所有块设备(如硬盘、分区、SSD、光盘等)信息的命令。它的输出默认以树状结构展示设备之间的层次关系(例如硬盘包含分区,分区又可能包含LVM卷等)。下面是对你提供的 lsblk --help 的详细解释,按功能和常用场景分类。
📌 基本用法
lsblk [选项] [设备...]
- 不加任何选项:列出所有非空的块设备,以树形显示。
- 可以指定一个或多个设备(例如
/dev/sda),只显示这些设备的信息。
🔧 常用选项详解(按场景分类)
1️⃣ 控制输出内容和格式
| 选项 | 作用 | 示例 |
|---|---|---|
-f, --fs | 显示文件系统信息(类型、UUID、挂载点等) | lsblk -f |
-m, --perms | 显示设备权限、所有者、组 | lsblk -m |
-t, --topology | 显示设备拓扑信息(队列长度、对齐、IO调度等) | lsblk -t |
-D, --discard | 显示设备的丢弃(TRIM)能力 | lsblk -D |
-S, --scsi | 只显示SCSI设备(包括SATA/SAS) | lsblk -S |
-N, --nvme | 只显示NVMe设备 | lsblk -N |
-o, --output | 自定义显示的列(配合 --list-columns 查看可用列) | lsblk -o NAME,SIZE,TYPE,MOUNTPOINT |
-O, --output-all | 输出所有可用列 | lsblk -O |
-J | 以 JSON 格式输出 | lsblk -J |
-P | 以 key="value" 格式输出(适合脚本解析) | lsblk -P |
2️⃣ 控制显示结构
| 选项 | 作用 | 示例 |
|---|---|---|
-l, --list | 使用列表格式(不显示树状结构,每个设备单独一行) | lsblk -l |
-T, --tree | 强制树状格式(可指定排序列) | lsblk -T |
-d, --nodeps | 只显示设备本身,不显示它的子设备(如分区) | lsblk -d |
-s, --inverse | 反向显示依赖关系(显示某个设备被谁使用) | lsblk -s /dev/sda1 |
3️⃣ 过滤和排除
| 选项 | 作用 | 示例 |
|---|---|---|
-a, --all | 显示所有设备,包括空的、没有分区的设备(如RAM盘) | lsblk -a |
-A, --noempty | 不显示空的设备 | 默认行为 |
-e, --exclude | 排除指定主设备号的设备(如 -e 1,7 排除RAM和loop设备) | lsblk -e 7(排除loop设备) |
-I, --include | 只显示指定主设备号的设备 | lsblk -I 8(只显示SCSI磁盘) |
-Q, --filter | 根据表达式过滤输出 | lsblk -Q 'TYPE=="part"' |
-E, --dedup | 去重输出(按指定列) | lsblk -E SIZE |
4️⃣ 辅助功能
| 选项 | 作用 | 示例 |
|---|---|---|
-b, --bytes | 以字节为单位显示大小(默认是易读格式如 K, M, G) | lsblk -b |
-p, --paths | 打印完整的设备路径(如 /dev/sda) | lsblk -p |
-n, --noheadings | 不打印表头 | lsblk -n |
-i, --ascii | 使用ASCII字符绘制树形结构(而不是UTF-8线条) | lsblk -i |
-w, --width | 设置输出宽度(字符数) | lsblk -w 100 |
-x, --sort | 按指定列排序 | lsblk -x SIZE |
-r, --raw | 原始输出(无表格对齐,适合脚本) | lsblk -r |
-y, --shell | 使用可被Shell接受的列名(用于变量赋值) | lsblk -y |
--sysroot | 指定其他系统根目录(用于急救环境) | lsblk --sysroot /mnt |
🎯 最常用的组合示例
| 目的 | 命令 |
|---|---|
| 查看所有磁盘分区和挂载点(最常见) | lsblk 或 lsblk -f |
| 只看硬盘本身,不显示分区 | lsblk -d |
| 以列表形式查看,方便脚本处理 | lsblk -l -o NAME,SIZE,TYPE,MOUNTPOINT |
| 查看磁盘是否支持 TRIM(SSD) | lsblk -D |
| 查看设备UUID和文件系统类型 | lsblk -f |
| 只显示SCSI/SATA磁盘 | lsblk -S |
| 输出JSON供程序解析 | lsblk -J |
📖 常用输出列解释
当你使用 -o 自定义列时,可以选择的常用列包括:
| 列名 | 含义 |
|---|---|
NAME | 设备名(如 sda, sda1) |
SIZE | 设备大小 |
TYPE | 类型(disk, part, lvm, rom等) |
MOUNTPOINT | 挂载点(如果已挂载) |
FSTYPE | 文件系统类型(如 ext4, xfs, ntfs) |
UUID | 文件系统UUID |
PARTUUID | 分区表UUID |
LABEL | 卷标 |
MODEL | 磁盘型号(仅对磁盘有效) |
SERIAL | 序列号 |
OWNER / GROUP / MODE | 设备文件权限(配合 -m) |
mdadm 是 Linux 下管理软件 RAID 阵列(Multiple Device)的核心工具。你贴出的 --help 列出了它的几种主要操作模式。下面我来为你逐一解释这些模式的用途和常用选项。
📌 基本语法
mdadm [模式] [设备] [选项...]
- 模式:决定要执行的操作(创建、组装、管理、监控等)。
- 设备:通常是 RAID 设备文件(如
/dev/md0)或成员设备(如/dev/sdb1)。
🎯 主要操作模式(你列出的那些)
1️⃣ --create(创建阵列)
从头创建一个新的 RAID 阵列。
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1
常用选项:
| 选项 | 说明 |
|---|---|
--level / -l | RAID 级别:0, 1, 4, 5, 6, 10 等 |
--raid-devices / -n | 阵列中活跃成员设备的数量 |
--spare-devices / -x | 热备盘数量 |
--chunk / -c | 数据块大小(单位 KB,默认为 512) |
--metadata / -e | 元数据格式(0.90, 1.0, 1.1, 1.2, default) |
--name / -N | 阵列名称(方便识别) |
--homehost | 设置阵列归属的主机名 |
--force / -f | 强制创建(忽略一些警告) |
2️⃣ --assemble(组装阵列)
将之前创建(但未激活)的阵列重新组合起来,通常用于系统启动时自动激活 RAID。
mdadm --assemble /dev/md0 /dev/sdb1 /dev/sdc1
常用选项:
| 选项 | 说明 |
|---|---|
--scan / -s | 扫描 /etc/mdadm/mdadm.conf 或自动检测并组装 |
--uuid | 根据 UUID 组装(而非设备路径) |
--name | 根据阵列名称组装 |
--force / -f | 强制组装,即使设备数量不足或状态不干净 |
--run / -R | 启动组装后的阵列(即使降级) |
3️⃣ --build(构建无元数据的阵列)
类似于 --create,但不写入任何元数据。通常用于非标准 RAID 或旧磁盘。
mdadm --build /dev/md0 --level=0 --raid-devices=2 /dev/sdb1 /dev/sdc1
⚠️ 使用场景非常有限,一般不建议普通用户使用。
4️⃣ --manage(管理运行中的阵列)
对已经激活的阵列进行动态管理,如添加、移除、标记故障等。
mdadm --manage /dev/md0 --add /dev/sdd1 --fail /dev/sdb1 --remove /dev/sdb1
子操作:
| 操作 | 说明 |
|---|---|
--add / -a | 添加一个新设备(可作为热备或恢复) |
--re-add | 重新添加之前移除的设备(通常用于替换后的重新加入) |
--fail / -f | 将某个成员标记为“故障” |
--remove / -r | 从阵列中移除一个设备(必须先标记为故障) |
--set-faulty | 同 --fail |
--replace | 替换一个故障设备 |
--spare | 将一个设备指定为热备盘 |
5️⃣ --misc(杂项操作)
查询、修改或停止阵列等。
mdadm --misc --detail /dev/md0 # 查看阵列详细信息
mdadm --misc --query /dev/sdb1 # 查询设备是否为 RAID 成员
mdadm --misc --stop /dev/md0 # 停止阵列
mdadm --misc --examine /dev/sdb1 # 检查设备上的超级块信息
mdadm --misc --zero-superblock /dev/sdb1 # 擦除设备上的 RAID 超级块
常用子操作:
| 选项 | 说明 |
|---|---|
--detail / -D | 显示阵列详细状态 |
--brief / -b | 简要输出(适合写入配置文件) |
--query / -Q | 检查设备是否属于 RAID |
--examine / -E | 查看设备上的 RAID 元数据 |
--examine-bitmap | 查看位图信息 |
--zero-superblock | 清除 RAID 超级块(彻底重置设备) |
--stop / -S | 停用阵列 |
--run / -R | 启动一个已停止的阵列 |
6️⃣ --grow(扩展/改变阵列)
在不重建阵列的情况下改变其属性(如增加 RAID 级别、改变设备数量等)。
mdadm --grow /dev/md0 --level=6 --raid-devices=4 --backup-file=/root/backup.md
常用选项:
| 选项 | 说明 |
|---|---|
--size | 改变每个设备使用的区域大小(通常用于扩容) |
--raid-disks / -n | 增加或减少设备数量(必须配合 --add 或 --remove) |
--level / -l | 在线改变 RAID 级别(如 1 → 5 → 6) |
--layout / -p | 改变布局(如 RAID10 的近远布局) |
--chunk | 改变块大小 |
--backup-file | 指定备份文件(对可能损坏数据的操作必须提供) |
⚠️ --grow 操作有一定风险,尤其减少设备或降级,务必先备份数据。
7️⃣ --incremental(增量添加设备)
用于系统热拔插事件,将新插入的磁盘自动添加到已有的阵列中(或启动降级阵列)。
mdadm --incremental /dev/sdb1
配合 udev 或 systemd 实现自动管理。
8️⃣ --monitor(监控模式)
持续监控一个或多个阵列,并在状态改变时发送邮件或执行动作。
mdadm --monitor --mail=admin@example.com --delay=300 /dev/md0
常用选项:
| 选项 | 说明 |
|---|---|
--mail / -m | 设置报警邮件地址 |
--delay / -d | 检查间隔(秒,默认 60) |
--scan / -s | 监控配置文件中列出的所有阵列 |
--program / -p | 状态改变时执行的脚本路径 |
--syslog | 记录到 syslog |
📄 常用辅助选项(适用于任何模式)
在 mdadm --help-options 中可以看到全部,下面列出常用的:
| 选项 | 说明 |
|---|---|
--config / -c | 指定配置文件(默认 /etc/mdadm/mdadm.conf) |
--verbose / -v | 输出详细过程 |
--quiet / -q | 安静模式(不输出多余信息) |
--force / -f | 强制执行(跳过检查) |
--yes | 自动回答“yes”(用于脚本) |
--dry-run | 模拟运行,不真实执行 |

Comments NOTHING