强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 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 0N1N × 单设备0
RAID 1 (2副本)N2N/2 × 单设备1
RAID 1 (3副本)N3N/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 缓存策略

6.7.1 Promote 缓存

# 配置 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 本章小结

配置设备数副本数适用场景
单设备11桌面/开发机
条带化N1临时存储/高性能
双副本2+2一般数据保护
三副本3+3关键数据
分层存储多种可选成本优化的存储服务器

扩展阅读


上一章: ← 第 5 章:高级特性 | 下一章: 第 7 章:快照管理 →