换了新本子,外存是1T机械硬盘和16G固态硬盘。这16G SSD 速度挺快的尤其是读的时候,可它拿来放 / 都不够呢,于是拿来作缓存加速。根据局部性原理,虽然数据很多,但是最常访问的只占其中一小部分呢。
搜索的结果是有三个方案:bcache、dm-cache 和 Facebook 的 flashcache。前两者在官方内核里,不需要另外安装。我是最先在 Arch Wiki 上看到 bcache 的,后来又看 dm-cache,发现需要自己指定元数组的存储什么的,略复杂。而且一些评测显示 bcache 性能要好一点,所以就它了。
$$ \require{extpfeil} \rm{SSD} + \rm{HDD} \xlongequal{\rm bcache} \rm{SSHD} $$
配置起来其实很简单。首先安装 AUR 里的 bcache-tools,然后创建存储数据的分区和用于缓存的分区:
make-bcache -B /dev/sda2
make-bcache -C /dev/sdb1
教程上使用的是 SSD 的分区。换成 SSD 的块设备本身应该也可以。
参数什么的我没调。然后是把缓存设备的 UUID 写到 /sys/block/bcache0/bcache/attach 里。
为了最优性能,往 /sys/block/bcache0/bcache/cache_mode 里写入「writeback」来更改其缓存策略为「写回」。默认是「写通」(writethrough),也就是写的时候同时写缓存和后端设备,不会在缓存出问题时丢数据,但是会慢。另一个可选的策略是「writearound」,不知道该怎么译,是只写到后端设备而不写缓存的。最后一个是「none」,不知道用了它会发生什么……
换出策略使用默认的 LRU(最近最少使用)。剩下的两个(FIFO 和随机)应该效果没 LRU 好。
这些设备是会记住的,无需在启动时重启配置。至少我用的 4.0.1 内核是这样。
弄好之后就可以折腾 /dev/bcache0 这个块设备了。我放弃了之前使用文件级的 eCryptfs,改用在备份里使用得挺爽的块设备级的 dm-crypt,然后才格式化成 ext4。也就是:
$$ 文件数据 \xrightarrow{\textrm{I/O相关系统调用}} \rm{ext4} \xrightarrow{加密} \textrm{dm-crypt} \xrightarrow{缓存} \rm{bcache} \xrightarrow{写入} \rm{SSD} + \rm{HDD} $$
所以我的 /etc/mkinitcpio.conf 里要加上 bcache 和 encrypt 两个 hook:
HOOKS="base udev autodetect modconf block bcache encrypt filesystems keyboard fsck resume"
(不过这样子不能用外接 USB 键盘输入密码的。)
然后 mkinitcpio -p linux 一下,生成新的 initramfs 镜像。
为了共享缓存,我把 / 和 /home 放一起了(不过我猜对 /dev/bcache0 进行分区也是可以的?)。虽然这样子整个 / 用去了60多G空间,但是缓存的命中率还是非常高的——
>>> bcache-status -a
--- bcache ---
Device /dev/bcache0 (254:0)
UUID 07a9b6a5-7f18-4950-84d6-c90abaaf65dc
Block Size 0.50KiB
Bucket Size 512.00KiB
Congested? False
Read Congestion 2.0ms
Write Congestion 20.0ms
Total Cache Size 14.91GiB
Total Cache Used 14.91GiB (100%)
Total Cache Unused 0B (0%)
Dirty Data 0.50KiB (0%)
Evictable Cache 14.17GiB (95%)
Replacement Policy [lru] fifo random
Cache Mode writethrough [writeback] writearound none
Last 5min Hits 439 (92%)
Last 5min Misses 38
Last 5min Bypass Hits 424 (100%)
Last 5min Bypass Misses 0
Last 5min Bypassed 61.50MiB
Last Hour Hits 46003 (88%)
Last Hour Misses 6051
Last Hour Bypass Hits 94043 (100%)
Last Hour Bypass Misses 0
Last Hour Bypassed 400.00MiB
Last Day Hits 79485 (88%)
Last Day Misses 10214
Last Day Bypass Hits 170383 (100%)
Last Day Bypass Misses 0
Last Day Bypassed 602.00MiB
Total Hits 79485 (88%)
Total Misses 10214
Total Bypass Hits 170383 (100%)
Total Bypass Misses 0
Total Bypassed 602.00MiB
bcache-status 脚本来自这里。
感觉还挺快的,特别是各种程序如火狐、gvim、pidgin、zsh 的启动速度,以及 mlocate、pacman 的搜索速度都非常快。没有对比数据,因为我没有试过在这个本子上不用 bcache 的情况下把系统弄起来。之前的旧本子可能因为分区太满导致碎片严重,所以 I/O 性能很差劲的。