logo

鱼肚的博客

Don't Repeat Yourself

有的机器上会配备一些小容量的SSD,在大多数时候,我们会选择将其作为系统盘(Windows),但是在用Linux制作一些服务器的时候,主要的性能瓶颈往往不在基础的系统文件上,而是对应的服务频繁读写的目录上。

比如Gitlab Runner可使用Docker模式进行构建,其主要的读写行为集中在 /var/lib/docker 目录下。

如果将相关存储直接写到小容量SSD上,往往是不够的,但是有SSD不用也实在是浪费。

经过一番搜索,我找到了一种使用小容量SSD做缓存,与机械硬盘联合成一块混合SSD的做法,在这里与大家分享下。

相关技术及其原理介绍

本次使用到的应用是bcache,它可以用来将一些较快的存储设备(如SSD),当作另一些较慢的存储设备(如HDD)的缓存。这样可以创建出性能尚可的混合存储。

bcache依赖于Linux 3.0以上的内核,大多数情况下应能满足。

其加速原理主要是如下几点:

  1. 使用SSD缓存随机读。因为HDD在寻道上的时间远大于读取数据的时间,而SSD有近乎于0的寻址时间,所以在缓存命中时会有很大的提升。
  2. 使用SSD缓存随机写,并将随机写操作合并后改成顺序写。这里一方面有和随机读相同的优化原理(减少寻址时间),另一方面也避免了SSD的写放大问题。
  3. 顺序读写会跳过缓存,直接进入HDD,避免大量冲刷SSD中的随机读缓存。

写放大:SSD在写入之前需要擦除,但是单位擦除的体积(如256KiB)远大于单位写入的体积(如4KiB)。

缓存模式

bcache支持三种模式:write-through(默认)、write-back、及write-around。它们的主要区别在写操作的处理上。

这也是所有缓存机制都面临的模式选择,不是bcache独有的。

下面简单介绍下三种模式的区别:

  • Write-through 同时写入到SSD和HDD,并在SSD和HDD都写成功后再返回成功。
  • Write-back 先写入到SSD,并返回成功,之后再后台同步到HDD。会带来一些稳定性风险。
  • Write-around 直接写入到HDD。

具体选择哪种模式,取决于业务对磁盘的使用方式。

以下是几种常见的决策方式:

  1. 如果对稳定性要求不高,但是对性能比较敏感,则应选择 Write-back,因其性能最高。
  2. 如果对稳定性有要求,则:
    1. 若是预期刚写入的数据会被较快重新读,则应使用Write-through,它在写入数据的同时,会在SSD上建立读缓存,后续读的时候速度会比较快。
    2. 若是很少读之前写入的数据,则应使用Write-around,一方面能加快写入速度(只用写一份),另一方面也避免了无效数据冲刷缓存。

配置方法

上面说了那么多原理,现在开始进入实操阶段吧。

首先,需要安装bcache-tools,根据系统的类型可分别使用 apt install bcache-toolsyum install bcache-tools等,不一一赘述。

然后需要准备两块磁盘(或分区),姑且假设分别用 /dev/sda2 做HDD,/dev/sdb做SSD。

1graph TB
2
3subgraph "/dev/bcache0"
4bcache --> ssd["SSD /dev/sdb"];
5bcache --> hdd["HDD /dev/sda2"];
6end

需要的两块存储,既可以是整块磁盘(/dev/sda),也可以是一个分区(/dev/sda2)。在执行bcache的时候,需要对相应的存储设备初始化,清空上面的所有数据。需要先做好备份!

首先安装bcache-tools

1$ sudo apt install bcache-tools

擦除对应设备上的数据

1$ sudo wipefs -a /dev/sda2 # backing device
2$ sudo wipefs -a /dev/sdb # cache device

格式化

1$ sudo make-bcache -B /dev/sda2 # backing device
2$ sudo make-bcache -C /dev/sdb # cache device

此时使用lsblk命令查看,应已经能查到 /dev/sda2 下面有个bcache0设备了。

关联Cache设备和Backing设备

先查看Cache设备的 set-uid 值。

1$ sudo bcache-super-show /dev/sdb | grep cset.uuid
2cset.uuid       9b1e7bf9-a97a-4785-bacb-0b17189adc08

复制上面的cset.uuid对应的值,即9b1e7bf9-a97a-4785-bacb-0b17189adc08,换成真实机器上的值。

执行关联

1# echo cset.uuid > /sys/block/bcache0/bcache/attach

上面的命令中,cset.uuid 要换成具体的值,类似于9b1e7bf9-a97a-4785-bacb-0b17189adc08这种。

这个时候再调用lsblk命令查看,应可以看到/dev/sda2和/dev/sdb下面各有一个bcache0设备了。

调整缓存模式

默认的模式是Write-through,如果想换成其它模式,如Write-back,则可以使用如下的命令来实现:

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

可选值有:writethrough writeback writearound none

挂载和使用分区

在上述步骤完成后,实际上混合SSD设备(/dev/bcache0) 已经就绪,可以开始使用了,用法和简单的磁盘分区无明显区别。

1$ sudo mkfs.ext4 /dev/bcache0
2$ sudo mount /dev/bcache0 /mnt

如果需要把挂载点固化,则需要更新到 /etc/fstab 文件,非本文重点,不再赘述。