第 6 章:多设备与分层存储
第 6 章:多设备与分层存储
让 SSD 做 SSD 该做的事,让 HDD 做 HDD 该做的事
6.1 多设备架构概述
6.1.1 设备角色模型
Bcachefs 设备角色:
┌─────────────────────────────────────────────────────┐
│ │
│ foreground (前台) → 存储热数据/元数据 │
│ background (后台) → 存储冷数据 │
│ journal (日志) → 专用日志设备 │
│ promote (提升) → SSD 缓存层 │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ 用户数据 I/O 请求 │ │
│ └──────────────────┬────────────────────────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Promote │ │Foreground│ │ Journal │ │
│ │ NVMe │ │ SSD │ │ NVMe │ │
│ └────┬────┘ └────┬─────┘ └──────────┘ │
│ │ │ │
│ └─────┬──────┘ │
│ ▼ │
│ ┌──────────┐ │
│ │Background│ │
│ │ HDD │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────┘
6.1.2 分层存储策略
| 数据类型 | 存储位置 | 原因 |
|---|
| 元数据 | SSD (foreground) | 小随机读写,需要低延迟 |
| 热数据 | SSD (foreground/promote) | 频繁访问 |
| 冷数据 | HDD (background) | 成本低,容量大 |
| 日志 | NVMe (journal) | 需要极低延迟 |
6.2 创建多设备文件系统
6.2.1 基本多设备
# 最简单的多设备:两个设备,无冗余(RAID 0)
sudo bcachefs format /dev/sdb /dev/sdc
# 等同于:
sudo bcachefs format /dev/sdb --device=/dev/sdc
6.2.2 带标签的多设备
# 使用标签标识设备角色
sudo bcachefs format \
--label=ssd.0 /dev/nvme0n1 \
--label=ssd.1 /dev/nvme1n1 \
--label=hdd.0 /dev/sdb \
--label=hdd.1 /dev/sdc \
--label=hdd.2 /dev/sdd
6.2.3 分层存储配置
# 完整的分层存储配置
sudo bcachefs format \
--label=nvme.0 /dev/nvme0n1 \
--label=ssd.0 /dev/sda \
--label=hdd.0 /dev/sdb \
--label=hdd.1 /dev/sdc \
--foreground_target=ssd \
--background_target=hdd \
--promote_target=nvme \
--metadata_target=ssd \
--replicas=2
6.2.4 完整创建脚本
#!/bin/bash
# create-tiered-storage.sh
set -e
# 设备定义
NVME="/dev/nvme0n1"
SSD1="/dev/sda"
SSD2="/dev/sdb"
HDD1="/dev/sdc"
HDD2="/dev/sdd"
HDD3="/dev/sde"
MOUNT_POINT="/mnt/storage"
echo "=== 创建分层存储文件系统 ==="
echo ""
echo "NVMe: $NVME (日志 + 缓存)"
echo "SSD: $SSD1, $SSD2 (前台存储)"
echo "HDD: $HDD1, $HDD2, $HDD3 (后台存储)"
echo ""
# 确认
read -p "这会清除所有设备上的数据!确认继续?(y/N) " confirm
if [ "$confirm" != "y" ]; then
echo "取消操作"
exit 0
fi
# 创建文件系统
sudo bcachefs format \
--label=nvme.0 $NVME \
--label=ssd.0 $SSD1 \
--label=ssd.1 $SSD2 \
--label=hdd.0 $HDD1 \
--label=hdd.1 $HDD2 \
--label=hdd.2 $HDD3 \
--foreground_target=ssd \
--background_target=hdd \
--promote_target=nvme \
--metadata_target=ssd \
--replicas=2 \
--compression=zstd \
--checksum=xxhash
# 挂载
sudo mkdir -p $MOUNT_POINT
sudo mount -t bcachefs \
${NVME}:${SSD1}:${SSD2}:${HDD1}:${HDD2}:${HDD3} \
$MOUNT_POINT
# 设置权限
sudo chown $USER:$USER $MOUNT_POINT
# 显示结果
echo ""
echo "=== 文件系统创建成功 ==="
sudo bcachefs device list $MOUNT_POINT
echo ""
df -h $MOUNT_POINT
6.3 设备管理
6.3.1 查看设备列表
# 列出所有设备
sudo bcachefs device list /mnt/data
# 输出示例:
# Device Label Type Status
# /dev/nvme0n1 nvme.0 nvme online
# /dev/sda ssd.0 sata online
# /dev/sdb hdd.0 sata online
# /dev/sdc hdd.1 sata online
6.3.2 添加设备
# 添加新 HDD 设备
sudo bcachefs device add --label=hdd.2 /mnt/data /dev/sdd
# 添加新 SSD 设备
sudo bcachefs device add --label=ssd.2 /mnt/data /dev/sde
# 验证添加
sudo bcachefs device list /mnt/data
6.3.3 移除设备
# 1. 先将数据迁移到其他设备
sudo bcachefs data migrate /mnt/data /dev/sdd
# 2. 等待迁移完成
# 可以通过以下命令监控进度
watch -n 5 'sudo bcachefs fs usage /mnt/data'
# 3. 移除设备
sudo bcachefs device remove /mnt/data /dev/sdd
# 4. 验证
sudo bcachefs device list /mnt/data
6.3.4 设备状态监控
# 查看设备详细信息
sudo bcachefs device show /mnt/data /dev/sdb
# 监控设备 I/O
iostat -x 1
# 检查设备健康
sudo bcachefs fsck /dev/sdb
6.4 RAID 配置详解
6.4.1 RAID 0(条带化)
# RAID 0: 数据分散到所有设备,无冗余
# 容量 = 所有设备容量之和
# 任一设备故障 → 数据丢失
sudo bcachefs format /dev/sdb /dev/sdc --replicas=1
6.4.2 RAID 1(镜像)
# RAID 1: 每个数据块存储 N 个副本
# 容量 = 单设备容量
# 可以容忍 N-1 个设备故障
# 双副本
sudo bcachefs format /dev/sdb /dev/sdc --replicas=2
# 三副本(需要 3+ 设备)
sudo bcachefs format /dev/sdb /dev/sdc /dev/sdd --replicas=3
6.4.3 元数据与数据分离冗余
# 数据双副本,元数据三副本
sudo bcachefs format \
/dev/sdb /dev/sdc /dev/sdd \
--replicas=2 \
--metadata_replicas=3
6.4.4 RAID 容量计算
| 配置 | 设备数 | 副本数 | 可用容量 | 容错 |
|---|
| RAID 0 | N | 1 | N × 单设备 | 0 |
| RAID 1 (2副本) | N | 2 | N/2 × 单设备 | 1 |
| RAID 1 (3副本) | N | 3 | N/3 × 单设备 | 2 |
6.4.5 RAID 降级处理
# 设备故障时的日志
dmesg | grep bcachefs
# [12345.678] bcachefs: device sdb failed
# [12345.679] bcachefs: filesystem degraded, 1 device(s) missing
# 查看降级状态
sudo bcachefs fs usage /mnt/data
# 显示 "degraded" 状态
# 替换故障设备
# 1. 添加新设备
sudo bcachefs device add --label=hdd.1 /mnt/data /dev/sdd
# 2. 重建数据(自动进行)
sudo bcachefs device set-state /mnt/data /dev/sdb failed
# 3. 移除旧设备
sudo bcachefs device remove /mnt/data /dev/sdb
6.5 数据迁移
6.5.1 设备间迁移
# 将数据从 HDD 迁移到 SSD
sudo bcachefs data migrate /mnt/data /dev/sdb
# 监控迁移进度
watch -n 2 'sudo bcachefs fs usage /mnt/data'
6.5.2 手动数据放置
# 将特定目录的数据放到 SSD
sudo bcachefs setattr /mnt/data/hot_data/ --target=ssd
# 将特定目录的数据放到 HDD
sudo bcachefs setattr /mnt/data/cold_data/ --target=hdd
6.5.3 数据提升策略
# 配置自动提升策略
# 当 SSD 上的数据被频繁访问时,自动提升到 NVMe
sudo mount -t bcachefs -o promote_threshold=10 /mnt/data
# promote_threshold: 访问次数阈值
# 达到阈值后自动将数据提升到 promote_target
6.6 日志设备配置
6.6.1 专用日志设备的优势
无专用日志设备:
写入流程: 数据 → Journal → 块设备
问题: Journal 和数据竞争 I/O
有专用日志设备:
NVMe → Journal (快速写入)
SSD/HDD → 数据 (顺序写入)
优势: 分离 I/O 路径,降低延迟
6.6.2 配置专用日志设备
# 创建带专用日志设备的文件系统
sudo bcachefs format \
--label=journal.0 /dev/nvme0n1 \
--label=data.0 /dev/sdb \
--label=data.1 /dev/sdc
# 挂载
sudo mount -t bcachefs /dev/nvme0n1:/dev/sdb:/dev/sdc /mnt/data
# 查看日志设备
sudo bcachefs device list /mnt/data
6.6.3 日志设备最佳实践
| 配置 | 推荐 |
|---|
| 设备类型 | NVMe SSD(低延迟) |
| 容量 | 1-10 GB(日志不会太大) |
| 冗余 | 使用 RAID 1 日志(2 个 NVMe) |
| 写入寿命 | 选择高 TBW 的企业级 SSD |
6.7 缓存策略
# 配置 promote 缓存
sudo bcachefs format \
--label=nvme.0 /dev/nvme0n1 \
--label=hdd.0 /dev/sdb \
--promote_target=nvme
# 工作原理:
# 1. 数据首先读取自 HDD
# 2. 如果被频繁访问(超过阈值)
# 3. 自动复制到 NVMe 缓存
# 4. 后续访问从 NVMe 读取
6.7.2 缓存调优参数
# 挂载选项
sudo mount -t bcachefs -o \
promote_threshold=5,\
promote_size_limit=1M \
/dev/nvme0n1:/dev/sdb /mnt/data
# promote_threshold: 触发提升的访问次数
# promote_size_limit: 只提升小于指定大小的数据块
6.7.3 缓存监控
# 查看缓存命中率
sudo bcachefs fs usage --verbose /mnt/data
# 监控 I/O 分布
iostat -x 1
# 观察各个设备的 I/O 分布
6.8 多设备故障恢复
6.8.1 设备故障场景
场景 1: 单设备故障(有副本)
→ 文件系统降级运行
→ 数据完整
→ 替换设备后自动重建
场景 2: 多设备故障(超过副本数)
→ 文件系统可能不可用
→ 可能有数据丢失
→ 需要 fsck 检查
场景 3: 所有设备故障
→ 数据完全丢失
→ 需要从备份恢复
6.8.2 设备替换流程
# 步骤 1: 识别故障设备
dmesg | grep bcachefs
# 输出: bcachefs: device sdb failed
# 步骤 2: 检查文件系统状态
sudo bcachefs fs usage /mnt/data
# 确认降级状态
# 步骤 3: 添加新设备
sudo bcachefs device add --label=hdd.1 /mnt/data /dev/sdd
# 步骤 4: 标记旧设备为故障
sudo bcachefs device set-state /mnt/data /dev/sdb failed
# 步骤 5: 移除旧设备
sudo bcachefs device remove /mnt/data /dev/sdb
# 步骤 6: 验证
sudo bcachefs device list /mnt/data
sudo bcachefs fs usage /mnt/data
6.8.3 紧急恢复
# 如果文件系统无法挂载
# 1. 使用只读模式挂载
sudo mount -t bcachefs -o ro,degraded /dev/sdb /mnt/data
# 2. 检查并修复
sudo umount /mnt/data
sudo bcachefs fsck --fix-errors /dev/sdb
# 3. 尝试重建分配信息
sudo bcachefs fsck --reconstruct-alloc /dev/sdb
6.9 性能优化
6.9.1 I/O 调度器选择
# 查看当前调度器
cat /sys/block/sdb/queue/scheduler
# 设置调度器
# NVMe: none (直接派发)
echo "none" | sudo tee /sys/block/nvme0n1/queue/scheduler
# SSD: mq-deadline
echo "mq-deadline" | sudo tee /sys/block/sda/queue/scheduler
# HDD: bfq (适合旋转磁盘)
echo "bfq" | sudo tee /sys/block/sdb/queue/scheduler
6.9.2 多设备 I/O 并发
# 调整并发 I/O 数量
echo 64 | sudo tee /sys/block/sdb/queue/nr_requests
# 队列深度
echo 32 | sudo tee /sys/block/nvme0n1/queue/nr_requests
6.9.3 数据分布优化
# 确保数据均匀分布
# 避免单设备成为瓶颈
sudo bcachefs fs usage /mnt/data
# 监控设备利用率
iostat -x 1
# 观察 %util 列,确保没有设备过载
6.10 完整示例
示例:家庭 NAS 配置
#!/bin/bash
# home-nas-setup.sh
set -e
echo "=== 家庭 NAS 配置 ==="
echo ""
echo "硬件配置:"
echo " - 1x NVMe 500GB (系统 + 缓存)"
echo " - 2x HDD 4TB (数据存储)"
echo ""
# 设备
NVME="/dev/nvme0n1"
HDD1="/dev/sdb"
HDD2="/dev/sdc"
MOUNT="/mnt/nas"
# 创建文件系统
sudo bcachefs format \
--label=nvme.0 $NVME \
--label=hdd.0 $HDD1 \
--label=hdd.1 $HDD2 \
--foreground_target=nvme \
--background_target=hdd \
--promote_target=nvme \
--metadata_target=nvme \
--replicas=2 \
--compression=zstd
# 挂载
sudo mkdir -p $MOUNT
sudo mount -t bcachefs \
${NVME}:${HDD1}:${HDD2} \
$MOUNT
# 设置权限
sudo chown $USER:$USER $MOUNT
# 创建目录结构
mkdir -p $MOUNT/{documents,photos,videos,music,backups}
# 配置 fstab
UUID=$(sudo bcachefs show-super $NVME | grep "UUID:" | awk '{print $2}')
echo "UUID=$UUID $MOUNT bcachefs defaults,noatime 0 0" | sudo tee -a /etc/fstab
echo ""
echo "=== NAS 配置完成 ==="
df -h $MOUNT
6.11 本章小结
| 配置 | 设备数 | 副本数 | 适用场景 |
|---|
| 单设备 | 1 | 1 | 桌面/开发机 |
| 条带化 | N | 1 | 临时存储/高性能 |
| 双副本 | 2+ | 2 | 一般数据保护 |
| 三副本 | 3+ | 3 | 关键数据 |
| 分层存储 | 多种 | 可选 | 成本优化的存储服务器 |
扩展阅读
上一章: ← 第 5 章:高级特性 | 下一章: 第 7 章:快照管理 →