4 用于块设备操作的多层缓存 #
多层缓存是一种复制的/分布式缓存,它至少包括两个层:一个层由速度较慢但较为廉价的旋转块设备(硬盘)表示,另一个层成本更高,但执行数据操作的速度更快(例如,SSD 闪存盘)。
SUSE Linux Enterprise Server 为闪存设备与旋转设备的缓存实施两种不同的解决方案:bcache
和 lvmcache
。
4.1 一般术语 #
本节对在介绍缓存相关功能时经常用到的几个术语进行了解释:
- 迁移
将逻辑块的主副本从一个设备移到另一个设备。
- 升级
从慢速设备迁移到快速设备。
- 降级
从快速设备迁移到慢速设备。
- 源设备
大型慢速块设备。它始终包含逻辑块的副本,该副本可能已过时或者与缓存设备上的副本保持同步(取决于策略)。
- 缓存设备
小型高速块设备。
- 元数据设备
一个小型设备,用于记录哪些块在缓存中、哪些块是脏的,以及供策略对象使用的附加提示。此信息可放在缓存设备上,但将它隔离可让卷管理器对它进行不同的配置,例如,配置为镜像以提高稳定性。元数据设备只能由单个缓存设备使用。
- 脏块
如果某个进程将信息写入缓存中的某个数据块,则该缓存的块将被标记为脏块,因为该块在缓存中已被覆盖,需要写回到原始设备。
- 缓存未命中
I/O 操作请求会先指向已缓存设备的缓存。如果找不到请求的值,则会在设备本身中查找,因此速度会变慢。这称为缓存未命中。
- 缓存命中
如果在已缓存设备的缓存中找到请求的值,则可以快速提供该值。这称为缓存命中。
- 冷缓存
不保存任何值(为空)且导致缓存未命中的缓存。在执行已缓存块设备的操作过程中,冷缓存中会填充数据,从而变为暖缓存。
- 暖缓存
已保存了一些值并且可能会导致缓存命中的缓存。
4.2 缓存模式 #
下面是多层缓存使用的基本缓存模式:写回、直写、绕写和直通。
- 写回
写入已缓存块的数据只会存入缓存,并且该块将标记为脏块。这是默认的缓存模式。
- 直写
只有在同时命中源设备和缓存设备之后,向已缓存块的写入才会完成。在直写缓存中,干净块将保持干净状态。
- 绕写
类似于直写缓存的一种技术,不过,写 I/O 将直接写入永久性存储,并绕过缓存。这可以防止缓存因写 I/O 而填满,导致以后不可重新读取,不过,缺点是对最近写入数据的读取请求会造成“缓存未命中”,因而需要从慢速大容量存储中读取这些数据,致使发生较高延迟。
- 直通
要启用直通模式,缓存必须是干净的。将绕过缓存,从源设备为读取请求提供服务。写请求将转到源设备,使缓存块“失效”。直通允许您激活缓存设备时不必考虑数据一致性,而这是可以维护的。随着写操作的不断进行,缓存将逐渐变为冷状态。如果您以后可以校验缓存的一致性,或者可以使用
invalidate_cblocks
消息来建立这种一致性,则可以在缓存设备仍处于暖状态时,将它切换到直写或写回模式。或者,可以在切换到所需的缓存模式之前,先丢弃缓存内容。
4.3 bcache
#
bcache
是一个 Linux 内核块层缓存。它允许使用一个或多个高速磁盘驱动器(例如 SSD)作为一个或多个速度低得多的硬盘的缓存。bcache
支持直写和写回,不受所用文件系统的约束。默认情况下,它只缓存随机读取和写入,这也是 SSD 的强项。它还适合用于台式机、服务器和高端存储阵列。
4.3.1 主要功能 #
可以使用单个缓存设备来缓存任意数量的后备设备。在运行时可以挂接和分离已挂载及使用中的后备设备。
在非正常关机后恢复 - 只有在缓存与后备设备一致后才完成写入。
SSD 拥塞时限制传至 SSD 的流量。
高效的写回实施方案。脏数据始终按排序顺序写出。
稳定可靠,可在生产环境中使用。
4.3.2 设置 bcache
设备 #
本节介绍设置和管理 bcache
设备的步骤。
安装
bcache-tools
软件包:>
sudo
zypper in bcache-tools创建后备设备(通常是一个机械驱动器)。后备设备可以是整个设备、一个分区或任何其他标准块设备。
>
sudo
make-bcache -B /dev/sdb创建缓存设备(通常是一个 SSD 磁盘)。
>
sudo
make-bcache -C /dev/sdc本示例使用了默认的块大小和存储桶大小,分别为 512 B 和 128 KB。块大小应与后备设备的扇区大小(通常为 512 或 4k)匹配。存储桶大小应与缓存设备的擦除块大小匹配,以便减少写入放大现象。例如,如果使用具有 4k 扇区的硬盘和具有 2 MB 擦除块大小的 SSD,则此命令将如下所示:
sudo make-bcache --block 4k --bucket 2M -C /dev/sdc
提示:多设备支持make-bcache
可同时准备和注册多个后备设备与一个缓存设备。在这种情况下,以后您不需要将缓存设备手动挂接到后备设备:>
sudo
make-bcache -B /dev/sda /dev/sdb -C /dev/sdcbcache
设备将显示为/dev/bcacheN
和
/dev/bcache/by-uuid/UUID /dev/bcache/by-label/LABEL
您可以像平时一样正常格式化和挂载
bcache
设备:>
sudo
mkfs.ext4 /dev/bcache0>
sudo
mount /dev/bcache0 /mnt您可以在
/sys/block/bcacheN/bcache
中通过sysfs
控制bcache
设备。注册缓存设备和后备设备后,需要将后备设备挂接到相关的缓存集才能启用缓存:
>
echo CACHE_SET_UUID > /sys/block/bcache0/bcache/attach其中,CACHE_SET_UUID 可在
/sys/fs/bcache
中找到。默认情况下,
bcache
使用直通缓存模式。要更改模式,例如,更改为写回模式,请运行>
echo writeback > /sys/block/bcache0/bcache/cache_mode
4.3.3 使用 sysfs
配置 bcache
#
bcache
设备使用 sysfs
接口来存储其运行时配置值。这样,您便可以更改 bcache
后备设备和缓存磁盘的行为,或查看其使用统计数字。
有关 bcache
sysfs
参数的完整列表,请查看 /usr/src/linux/Documentation/bcache.txt
文件的内容,主要查看 SYSFS - BACKING DEVICE
、SYSFS - BACKING
DEVICE STATS
和 SYSFS - CACHE DEVICE
部分。
4.4 lvmcache
#
lvmcache
是由逻辑卷 (LV) 组成的缓存机制。它使用 dm-cache
内核驱动程序,支持直写(默认)和写回缓存模式。lvmcache
可将大型慢速 LV 的部分数据动态迁移到更快、更小的 LV,从而提高其性能。有关 LVM 的详细信息,请参见第 II 部分 “逻辑卷 (LVM)”。
LVM 将小型快速 LV 称为缓存池 LV。大型慢速 LV 称为源 LV。由于 dm-cache 的要求,LVM 进一步将缓存池 LV 分割成两个设备:缓存数据 LV 和缓存元数据 LV。来自源 LV 的数据块副本保存在缓存数据 LV 中,以提高速度。缓存元数据 LV 保存记帐信息,这些信息指定数据块的存储位置。
4.4.1 配置 lvmcache
#
本节介绍创建和配置基于 LVM 的缓存的步骤。
创建源 LV。创建新 LV,或使用现有 LV 作为源 LV:
>
sudo
lvcreate -n ORIGIN_LV -L 100G vg /dev/SLOW_DEV创建缓存数据 LV。此 LV 将保存来自源 LV 的数据块。此 LV 的大小是缓存的大小,将报告为缓存池 LV 的大小。
>
sudo
lvcreate -n CACHE_DATA_LV -L 10G vg /dev/FAST创建缓存元数据 LV。此 LV 将保存缓存池元数据。此 LV 的大小应该比缓存数据 LV 大约小 1000 倍,其最小大小为 8MB。
>
sudo
lvcreate -n CACHE_METADATA_LV -L 12M vg /dev/FAST列出您目前为止所创建的卷:
>
sudo
lvs -a vg LV VG Attr LSize Pool Origin cache_data_lv vg -wi-a----- 10.00g cache_metadata_lv vg -wi-a----- 12.00m origin_lv vg -wi-a----- 100.00g创建缓存池 LV。将数据 LV 和元数据 LV 组合成一个缓存池 LV。同时还可以设置缓存池 LV 的行为。
CACHE_POOL_LV 会采用 CACHE_DATA_LV 的名称。
CACHE_DATA_LV 会重命名为 CACHE_DATA_LV_cdata 并隐藏起来。
CACHE_META_LV 会重命名为 CACHE_DATA_LV_cmeta 并隐藏起来。
>
sudo
lvconvert --type cache-pool \ --poolmetadata vg/cache_metadata_lv vg/cache_data_lv>
sudo
lvs -a vg LV VG Attr LSize Pool Origin cache_data_lv vg Cwi---C--- 10.00g [cache_data_lv_cdata] vg Cwi------- 10.00g [cache_data_lv_cmeta] vg ewi------- 12.00m origin_lv vg -wi-a----- 100.00g创建缓存 LV。通过将缓存池 LV 链接到源 LV 来创建缓存 LV。
用户可访问的缓存 LV 与源 LV 同名,源 LV 将变成重命名为 ORIGIN_LV_corig 的隐藏 LV。
CacheLV 会采用 ORIGIN_LV 的名称。
ORIGIN_LV 会重命名为 ORIGIN_LV_corig 并隐藏起来。
>
sudo
lvconvert --type cache --cachepool vg/cache_data_lv vg/origin_lv>
sudo
lvs -a vg LV VG Attr LSize Pool Origin cache_data_lv vg Cwi---C--- 10.00g [cache_data_lv_cdata] vg Cwi-ao---- 10.00g [cache_data_lv_cmeta] vg ewi-ao---- 12.00m origin_lv vg Cwi-a-C--- 100.00g cache_data_lv [origin_lv_corig] [origin_lv_corig] vg -wi-ao---- 100.00g
4.4.2 去除缓存池 #
可通过多种方法关闭 LV 缓存。
4.4.2.1 从缓存 LV 分离缓存池 LV #
您可以从缓存 LV 断开与缓存池 LV 的连接,留下一个未使用的缓存池 LV 和一个未缓存的源 LV。数据将根据需要从缓存池写回到源 LV。
>
sudo
lvconvert --splitcache vg/origin_lv
4.4.2.2 去除缓存池 LV 但不去除其源 LV #
以下命令会根据需要将数据从缓存池写回到源 LV,然后去除缓存池 LV,留下未缓存的源 LV。
>
sudo
lvremove vg/cache_data_lv
也可以使用以下替代命令从缓存 LV 断开与缓存池的连接,并删除缓存池:
>
sudo
lvconvert --uncache vg/origin_lv
4.4.2.3 去除源 LV 和缓存池 LV #
去除缓存 LV 会同时去除源 LV 和链接的缓存池 LV。
>
sudo
lvremove vg/origin_lv
4.4.2.4 更多信息 #
可以在 lvmcache
手册页 (man 7
lvmcache
) 中找到有关 lvmcache
的更多主题,例如支持的缓存模式、冗余的子逻辑卷、缓存策略,或者将现有 LV 转换为缓存类型。