前言

在Linux下,使用SSD为HDD加速,目前较为成熟的方案有:flashcache,enhanceIO,dm-cache,bcache等,多方面比较以后最终选择了bcache。 bcache 是一个 Linux 内核块层超速缓存。它允许使用一个或多个高速磁盘驱动器(例如 SSD)作为一个或多个速度低得多的硬盘的超速缓存。bcache 支持直写和写回,不受所用文件系统的约束。默认情况下,它只超速缓存随机读取和写入,这也是 SSD 的强项。它还适合用于台式机、服务器和高端储存阵列。CentOS和Ubuntu都可以使用bcache。bcache是在3.10以后的版本加入mainline的,因此需要3.10以上的内核版本。但是笔者使用Centos 7在3.10.0的内核上进行配置时,发现无法生成相应的配置文件节点,测试过程中使用4.3.3版的内核。

首先我们先明白几个概念

既然是缓存,那自然就会想到缓存策略,bcache支持三种缓存策略:

  • writeback:回写策略,所有的数据将先写入缓存盘,然后等待系统将数据回写入后端数据盘中。(性能最好)
  • writethrough:直写策略(默认策略),数据将会同时写入缓存盘和后端数据盘。
  • writearoud:数据将直接写入后端磁盘。(性能最差)

主要功能:

1,可以使用单个超速缓存设备来超速缓存任意数量的后备设备。在运行时可以挂接和分离已装入及使用中的后备设备。

2,在非正常关机后恢复 - 只有在超速缓存与后备设备一致后才完成写入。

3,SSD 拥塞时限制传至 SSD 的流量。

4,高效的写回实施方案。脏数据始终按排序顺序写出。

5,稳定可靠,可在生产环境中使用。

Bcache通过make-bcache命令完成bcache的创建,需要安装相关的工具包bcache-tools。

我们通过编译安装 (Github)

https://github.com/g2p/bcache-tools/archive/refs/tags/v1.0.8.tar.gz

这是最新的v1.0.8,如果要查看其他版本请访问

Tags · g2p/bcache-tools · GitHub

下载源码(我这里使用了github链接代理加速)

1
wget https://github.moeyy.xyz/https://github.com/g2p/bcache-tools/archive/refs/tags/v1.0.8.tar.gz

解压源码压缩包

1
tar -zxvf v1.0.8.tar.gz 

安装依赖

1
yum install libblkid-devel -y

编译安装

如果没有make命令请自行安装软件包

1
make && make install

格式化硬盘分区

应用硬盘到bcache模式之前需要将目标分区格式化为bcache,这一步会破坏磁盘分区中所有数据。方法和信息如下

1
# 如果磁盘是第一次使用,或完全是空的,第一步通常不用执行,这一步市为了擦除分区文件信息,如果挂载也要先卸载,否则会出现device busy的问题wipefs -a /dev/sdb /dev/sdc

创建cache 也就是我们的SSD的分区作为缓存

缓存参数意义:

-B: 设置backing device
-C: 设置cache device
-w: block size (hard sector size of SSD),默认是2K,可使用–block=4K代替
-b: bucket size,可以使用–bucket=1M代替

1
make-bcache -C /dev/sdc1

查看下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@master ~]# bcache-super-show /dev/sdc1
sb.magic ok
sb.first_sector 8 [match]
sb.csum C322F881FE092899 [match]
sb.version 0 [cache device]

dev.label (empty)
dev.uuid d3834fdd-d31d-4347-9da3-31064cae77ac
dev.sectors_per_block 1
dev.sectors_per_bucket 1024
dev.cache.first_sector 1024
dev.cache.cache_sectors 20968448
dev.cache.total_sectors 20969472
dev.cache.ordered no
dev.cache.discard no
dev.cache.pos 0
dev.cache.replacement 0 [lru]

cset.uuid 0609854c-f083-408b-8ea6-f90d4afd60c6

创建backend

接着创建被加速的backend 

1
make-bcache -B /dev/sdb

这快硬盘就是我们的HDD机械硬盘

查看下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master ~]# bcache-super-show /dev/sdb
sb.magic ok
sb.first_sector 8 [match]
sb.csum C71B7848F1913A17 [match]
sb.version 1 [backing device]

dev.label (empty)
dev.uuid da958760-83c8-4d05-9789-f8b371bd62aa
dev.sectors_per_block 1
dev.sectors_per_bucket 1024
dev.data.first_sector 16
dev.data.cache_mode 0 [writethrough]
dev.data.cache_state 0 [detached]

cset.uuid 9a492f33-f28d-41f8-8cb1-3cfd93d07885

可能出现的错误

  • Device or resource busy 设备被占用,用 df 命令查看设备是不是已经被挂载使用,用 umount 取消挂载。
  • Device /dev/sdX already has a non-bcache superblock 设备已存在文件系统,为避免文件丢失,请在备份文件后,使用 sudo wipefs -a /dev/sdX 清除设备。

设备绑定

往backend附加cache

此处附加的uuid,是在上面查询到的cache的uuid 直接写  被加速的硬盘的 cset.uuid就行了

1
echo 9a492f33-f28d-41f8-8cb1-3cfd93d07885 > /sys/block/bcache0/bcache/attach

那上面的操作有没有可以一次性解决的命令呢,是有的

1
make-bcache -C /dev/sdc -B /dev/sdb
  • -C /dev/sdc:表示将 /dev/sdc 设备作为 Bcache 的缓存设备。缓存设备用于加速主存储设备的读写操作也就是SSD。
  • -B /dev/sdb:表示将 /dev/sdb 设备作为 Bcache 的后端(backend)设备。后端设备是实际存储数据的设备,可以是机械硬盘。

通过这个命令,你可以将一个普通的块设备(例如硬盘)和一个更快的设备(例如固态硬盘)结合起来,利用快速的缓存设备提高数据的访问速度。

上面这条命令,就自动的完成了上面的几个步骤,执行完之后看下盘的状态

1
2
3
4
5
6
7
8
9
10
11
[root@master ~]# lsblk 
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 20G 0 disk
└─bcache0 253:0 0 20G 0 disk
sr0 11:0 1 1024M 0 rom
sdc 8:32 0 10G 0 disk
└─bcache0 253:0 0 20G 0 disk
sda 8:0 0 53G 0 disk
├─sda2 8:2 0 2G 0 part
├─sda3 8:3 0 50.7G 0 part /
└─sda1 8:1 0 300M 0 part /boot

看到了两个盘都多了一个bcache0,这个可以理解为一块缓存盘和一个被加速盘的总体

格式化这个bcache0就可以当成正常分区来使用了

改成回写缓存模式

1
echo "writeback" > /sys/block/bcache0/bcache/cache_mode

这里注意下bcache默认创建的分区(bcache0)是MBR格式的,我前面的文章提到过MBR最大支持的容量为3T

如果没有上面的路径,可能是由于你的[内核]没有包含bcache模块,解决方法查看我们另外一篇文章
Linux内核编译添加bcache

卸载bcache缓存设备

查看cache的uuid

1
bcache-super-show /dev/sdc

删除缓存盘

要将缓存盘从当前的后端磁盘删除,只需将缓存盘的cset.uuid detach到bcache磁盘即可实现

1
echo c0d007af-93a9-4bf9-b067-926bd588983c > /sys/block/bcache0/bcache/detach

注销缓存盘

注销缓存前,请先确保当前缓存盘没有作为缓存使用,即通过lsblk看不到缓存磁盘下面的bcahe设备,如果当前磁盘正在使用,而进行注销操作,可能导致缓存盘的数据不能及时写入后端磁盘,造成数据丢失。
通过缓存盘的cset.uuid,在 /sys/fs/bcache/<cset.uuid>/unregister写入1,即可进行注销操作,操作如下:

1
echo c0d007af-93a9-4bf9-b067-926bd588983c > /sys/fs/bcache/c0d007af-93a9-4bf9-b067-926bd588983c/unregister 

Bcache调优

1.打开顺序IO缓存 (默认没有开启)

1
echo 0 > /sys/block/bcache0/bcache/sequential_cutoff

2.关闭读写拥塞控制命令

如果你的SSD足够强大,可以不跟踪,减少跟踪的开销。

bcache会跟踪每个IO,如果IO的时间超过阈值,则旁路cache设备,直接读写backing设备。

关闭旁路的另一个好处是,所有的离散读写都会经过cache设备,从而不会导致cache missing。

默认情况下当读请求超过2ms,写请求超过20ms时,旁路cache设备。

1
echo 0 > /sys/fs/bcache/{cache set uuid}/congested_read_threshold_us
1
echo 0 > /sys/fs/bcache/{cache set uuid}/congested_write_threshold_us

3.设置磁盘的预读缓存

1
echo "8192" > /sys/block/sdb/queue/read_ahead_kbecho "8192" > /sys/block/sdc/queue/read_ahead_kb

4.提高缓存盘缓存比例

1
echo 40 > /sys/block/bcache0/bcache/writeback_percent

一般writeback_percent常见设定是默认的10%,因为比例越高意味越多脏数据还没刷入后端数据盘,如果writeback模式,缓存盘挂了意味着数据损坏。