Home
avatar

Nax

Linux下使用bcache为HDD机械硬盘添加SSD缓存

在这篇教程中,我记录了一次为服务器上的大容量机械硬盘(HDD)添加SSD缓存的完整过程。我的目标是从一块已安装操作系统的SSD上,分割出一部分空间,利用Linux内核强大的bcache功能,来为HDD提供高速读写缓存,从而显著提升其I/O性能。 这个过程涉及分区调整、文件系统缩容、设备名变化等多个“坑”,本教程将一一记录并提供解决方案。

〇、环境与目标

  • 硬件配置:
    • 一块 50GB SSD,已安装操作系统 (/dev/vda)
    • 一块 2TB HDD,用作数据盘 (/dev/vdb)
  • 核心目标:
    1. 将 50GB 的 SSD 系统分区无损缩小至 30GB。
    2. 利用剩余的 20GB 空间作为缓存分区。
    3. 将 20GB 的SSD缓存与 2TB 的HDD绑定,创建一个名为 bcache0 的高性能虚拟设备。

一、进入正确的救援环境(踩坑点一)

调整一个正在运行的系统分区是极其危险且不被允许的。因此,第一步必须进入一个完全独立于目标硬盘的“离线”救援环境。

1.1 错误的尝试

最初,我通过服务商面板进入了“救援模式”,但执行e2fsck检查磁盘时,系统提示设备已被挂载:

root@rescue:~# e2fsck -f /dev/vda1
/dev/vda1 is mounted.
e2fsck: Cannot continue, aborting.

尝试卸载时,又提示目标忙:

root@rescue:~# umount /dev/vda1
umount: /: target is busy.

通过df -h命令我发现,这个救援系统依然是从我自己的硬盘启动的/dev/vda1被挂载为了根目录/。在这种模式下,我无法对自己“动刀”。

1.2 正确的诊断与进入

真正的救援模式应该从独立的介质(如网络、虚拟CD-ROM)启动。在重新启用救援模式后,我使用fdisk -l才知道哪哈错了:

root@rescue:~# fdisk -l
Disk /dev/vda: 4 GiB ...  <-- 这是一个独立的4GB救援系统盘
Device      Start   End    Sectors Size Type
/dev/vda1    2048 8388573 8386526   4G Linux filesystem

Disk /dev/vdb: 50 GiB ...  <-- 这才是我的目标SSD系统盘
Device      Start       End   Sectors Size Type
/dev/vdb1    2048 104857565 104855518  50G Linux filesystem

Disk /dev/vdc: 1.95 TiB ... <-- 这是我的HDD数据盘

看到这就脱了!它表明我当前的环境是安全且正确的。救援系统运行在/dev/vda上,我的目标SSD /dev/vdb和HDD /dev/vdc都处于离线状态,可以安全操作。

记住救援模式下的设备名:

  • 目标SSD: /dev/vdb
  • 目标HDD: /dev/vdc

二、无损调整SSD分区

这是整个过程中风险最高的一步,在操作前请务必备份好 /dev/vdb1 上的所有重要数据!

2.1 检查并修复文件系统

在调整大小前,必须确保文件系统是健康的。

sudo e2fsck -f /dev/vdb1

过程中,系统可能会发现一些不一致,比如“Free blocks count wrong”,并询问Fix<y>?。对所有问题都输入y并回车,让工具自动修复。

技巧:可以使用 e2fsck -fy /dev/vdb1 命令来自动对所有问题回答“yes”。

2.2 缩小文件系统

关键原则: 必须先缩小文件系统,再缩小其所在的分区。 我将把文件系统缩小到29GB,比目标分区大小30GB略小,以留出安全余量。

sudo resize2fs /dev/vdb1 29G

2.3 重新划分分区

使用fdisk工具对50GB的SSD (/dev/vdb)进行操作。

sudo fdisk /dev/vdb

fdisk的交互式命令行中,依次执行:

  1. 输入 d:删除当前的分区1。
  2. 输入 n:创建新分区。
    • Partition number: 1 (回车)
    • First sector: 2048 (直接回车,使用默认的起始扇区,这至关重要!)
    • Last sector: +30G (创建一个30GB的分区)
  3. 关键提问:系统会检测到旧的文件系统签名,并提问: Partition #1 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o: 必须输入 N 并回车! 选择No是为了保留我之前缩小的文件系统和数据。
  4. 再次输入 n:创建第二个分区(缓存分区)。
    • Partition number: 2 (回车)
    • First sector: (直接回车,使用默认值)
    • Last sector: (直接回车,使用所有剩余空间)
  5. 输入 p:检查新的分区表,确认 /dev/vdb1 约30GB,/dev/vdb2 约20GB。
  6. 输入 w:确认无误后,保存更改并退出。

三、在救援模式下创建bcache设备

分区准备就绪,接下来就是将HDD和SSD缓存分区绑定。

3.1 格式化设备

  • 将HDD (/dev/vdc) 格式化为后端设备 (Backing Device):
    sudo make-bcache -B /dev/vdc
  • 将新的SSD分区 (/dev/vdb2) 格式化为缓存设备 (Caching Device):
    sudo make-bcache -C /dev/vdb2

3.2 附加缓存

# 查看并复制cset.uuid
sudo bcache-super-show /dev/vdb2

# 将<CSET_UUID>替换为上面复制的值
echo <CSET_UUID> > /sys/block/vdc/bcache/attach

此时,lsblk应该能看到新的/dev/bcache0设备了。救援模式下的任务全部完成!

四、重启进入主系统并激活bcache(踩坑点二)

现在,可以从服务商面板禁用救援模式,让服务器正常启动,然后通过SSH登录。

4.1 问题诊断:设备名改变与bcache设备消失

登录主系统后,我发现/dev/bcache0不见了。 首先,检查磁盘名称,发现发生了设备名漂移

root@smcjnvsss8:~# fdisk -l
Disk /dev/vda: 50 GiB ... <-- 在主系统里,SSD变成了vda
Device      Start      End   Sectors Size Type
/dev/vda1      2048 62916607  62914560  30G Linux filesystem
/dev/vda2  62916608 10485551  41938944  20G Linux filesystem

Disk /dev/vdb: 1.95 TiB ... <-- HDD变成了vdb

记住主系统下的设备名:

  • SSD缓存分区: /dev/vda2
  • HDD: /dev/vdb

接着,我尝试手动注册设备,但系统报错No such file or directory,这说明bcache内核模块没有自动加载。

4.2 解决方案:加载模块并手动注册

  1. 安装bcache工具(如果系统没有预装):
    sudo apt-get update
    sudo apt-get install bcache-tools
  2. 手动加载内核模块
    sudo modprobe bcache
  3. 使用正确的设备名重新注册
    sudo echo /dev/vda2 > /sys/fs/bcache/register
    sudo echo /dev/vdb > /sys/fs/bcache/register

执行完毕后,再次运行lsblk,激动人心的/dev/bcache0设备终于出现了!

五、格式化、挂载并永久使用

这是最后的收尾工作,让我的新设备真正可用。

  1. 格式化bcache设备
    sudo mkfs.ext4 /dev/bcache0
  2. 创建挂载点
    sudo mkdir /data
  3. 挂载设备
    sudo mount /dev/bcache0 /data
  4. 设置开机自动挂载(最稳妥的方式):
    • 获取设备的UUID:
      sudo blkid /dev/bcache0
      复制 UUID="..." 引号内的长字符串。
    • 编辑fstab文件:
      sudo nano /etc/fstab
    • 在文件末尾添加新的一行(请替换成你自己的UUID):
      UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   /data   ext4   defaults   0   2
    • 保存并退出。

总结

至此,我已经成功地完成了从规划、分区、踩坑到最终配置的全过程。服务器现在拥有一个由SSD高速缓存的2TB数据盘,兼顾了容量与性能。

核心要点回顾:

  • 环境是关键:必须在真正的离线救援环境中操作目标磁盘。
  • 顺序很重要:必须先缩小文件系统,再缩小分区。
  • 注意设备名:救援模式和主系统的设备名可能会变化,要随时用fdisk -llsblk确认。
  • 模块要加载:主系统可能需要手动加载bcache内核模块才能识别设备。
  • 善用UUID:在fstab中使用UUID挂载,可以避免因设备名变化导致的启动失败问题。

希望这篇详细的实战记录能帮助到有同样需求的你!

linux hdd bcache 缓存