bcache
是 Linux 内核级别提供的一种缓存方案(要求内核版本 3.10+
并且内核编译时内部有加入 bcache 支持), 可以使用一个 SSD 的分区或整块硬盘空间作为另一个大容量 HDD 分区的特定缓存来加速 HDD 的随机读写操作.
下面将记录在 CentOS 7
上安装并配置的实验过程.
install #
CentOS 7
官方并未提供 bcache 的模块支持, 可以自己编译 bcache 模块或者使用别人已打包好的 rpm 源.
自行编译 bcache 模块需要整个 linux kernel source, 使用官方发行版内核来编译模块的话, 根据官方指导获得你需要的版本的 源码
这里初略概括下根据官方指导的如何 编译模块, 我们这里选择第一种 build *.ko
的方式
在 kernel 源码目录, 我们首先需要获取你期望编译的 kernel 版本的 kernel configuration
文件:
Module.symvers
.config
# 命令来自 https://wiki.archlinux.org/index.php/Compile_kernel_module
$ cp /usr/lib/modules/$(uname -r)/build/.config ./
$ cp /usr/lib/modules/$(uname -r)/build/Module.symvers ./
如果没复制
Module.symvers
, 编译会出现no symbol version for module_layout
错误.
上面命令的使用了 uname -r
来直接定位到当前系统运行的内核版本的 source 目录, 如果你不是编译当前运行的内核的 bcache 模块可自行指定 kernel 的 source 目录.
make oldconfig
后再 make menuconfig
, 根据文档找到 bcache 的配置,将其选择为 M
, 表示编译为模块.
其他步骤按官方步骤执行, 若中途出错一般是未安装某些软件, 可以根据出错提示, 安装对应软件解决.
模块编译后, 还要根据发行版的约束将模块设置为 boot 时加载, 需要在 /etc/modules-load.d/
目录下新建 /etc/modules-load.d/bcache.conf
, 加入内容
# Load bcache.ko at boot
# See the modules-load.d(5) and systemd-modules-load.service(8) man pages for more information.
bcache
bcache-tools #
内核模块编译完成后, 还需要 userspace tools 的支持, 就是 bcache-tools
软件包.
此软件包不光提供了常用的命令行工具, 还会自动的生成 udev rules
.
目前 red hat 系和 debian 系的 bcache-tools
工具集里的 udev rules
等略有差别, 源码及下载地址都不一样, fedora 20
以上的系统源里已包含此工具集, 包名就叫 bcache-tools
具体不同发行版的安装方式, 从 bcache 的 官方网址 摘抄可见
Bcache has been merged into the mainline Linux kernel; for the latest stable bcache release use the latest 3.10 or 3.11 stable kernel.
For the userspace tools,
git clone http://evilpiepirate.org/git/bcache-tools.git
The udev rules, Debian/Ubuntu source package, and Ubuntu PPA are maintained here:
git clone https://github.com/g2p/bcache-tools.git
To use the PPA (Ubuntu Raring and Saucy):
sudo add-apt-repository ppa:g2p/storage sudo apt-get update sudo apt-get install bcache-tools
The PPA also contains blocks, a conversion tool.
A Fedora package is available in Fedora 20, and maintained here.
make-bcache #
安装完成用户态工具 bcache-tools
后, 使用其中的 make-bcache
来操作磁盘
[root@pure-test ~]# make-bcache --help
Usage: make-bcache [options] device
-C, --cache Format a cache device
-B, --bdev Format a backing device
-b, --bucket bucket size
-w, --block block size (hard sector size of SSD, often 2k)
-o, --data-offset data offset in sectors
--cset-uuid UUID for the cache set
--writeback enable writeback
--discard enable discards
--cache_replacement_policy=(lru|fifo)
-h, --help display this help and exit
对设备进行操作前需要先清理整个设备的分区及其他信息:
# wipefs -a 'devices'
wipefs -a /dev/sda2 # 分区
wipefs -a /dev/sdb # 整个磁盘
device
可以是整个磁盘, 也可以是一个分区
假设 /dev/sdb
是一块ssd, /dev/sda
是一块HDD, 现在使用 /dev/sdb1
作为 cache, /dev/sda2
作为 backend, 2 个分区都已经使用 wipefs 处理过. 接下来就开始分别创建 cache 设备和 backend 设备.
cache #
生成 cache 设备
[root@pure-test ~]# make-bcache -C /dev/sdb1
UUID: bf8f710d-5c99-4d40-8747-00d72a5af2cf
Set UUID: 5da393d6-b157-4bb3-a105-235a1425894d
version: 0
nbuckets: 244206
block_size: 1
bucket_size: 1024
nr_in_set: 1
nr_this_dev: 0
first_bucket: 1
UUID
–> 实体设备 /dev/sdb1 的 UUID
Set UUID
–> 此 cache 设备被虚拟的 UUID –> 5da393d6-b157-4bb3-a105-235a1425894d
此 UUID 还可以通过查看 /sys/fs/bcache/
来确定
[root@pure-test ~]# ls -lh /sys/fs/bcache/
total 0
drwxr-xr-x 7 root root 0 Sep 28 15:15 5da393d6-b157-4bb3-a105-235a1425894d
--w------- 1 root root 4.0K Sep 28 15:15 register
--w------- 1 root root 4.0K Sep 28 15:15 register_quiet
查看此 cache 设备对应的实体设备
[root@pure-test ~]# ls -lh /sys/fs/bcache/5da393d6-b157-4bb3-a105-235a1425894d/
total 0
-r--r--r-- 1 root root 4.0K Sep 29 10:49 average_key_size
-r--r--r-- 1 root root 4.0K Sep 29 10:49 block_size
-r--r--r-- 1 root root 4.0K Sep 29 10:49 btree_cache_size
-r--r--r-- 1 root root 4.0K Sep 29 10:49 bucket_size
lrwxrwxrwx 1 root root 0 Sep 29 10:49 cache0 -> ../../../devices/pci0000:00/0000:00:1f.2/ata6/host5/target5:0:0/5:0:0:0/block/sdb/sdb1/bcache
-r--r--r-- 1 root root 4.0K Sep 29 10:49 cache_available_percent
--w------- 1 root root 4.0K Sep 29 10:49 clear_stats
-r--r--r-- 1 root root 4.0K Sep 29 10:49 congested
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 congested_read_threshold_us
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 congested_write_threshold_us
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 errors
--w------- 1 root root 4.0K Sep 29 10:49 flash_vol_create
drwxr-xr-x 2 root root 0 Sep 29 10:49 internal
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 io_error_halflife
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 io_error_limit
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 journal_delay_ms
-r--r--r-- 1 root root 4.0K Sep 29 10:49 root_usage_percent
drwxr-xr-x 2 root root 0 Sep 29 10:49 stats_day
drwxr-xr-x 2 root root 0 Sep 29 10:49 stats_five_minute
drwxr-xr-x 2 root root 0 Sep 29 10:49 stats_hour
drwxr-xr-x 2 root root 0 Sep 29 10:49 stats_total
--w------- 1 root root 4.0K Sep 29 10:49 stop
-rw-r--r-- 1 root root 4.0K Sep 29 10:49 synchronous
-r--r--r-- 1 root root 4.0K Sep 29 10:49 tree_depth
--w------- 1 root root 4.0K Sep 29 10:49 unregister
可以看见此块 cache 设备对应的是 /dev/sdb1
bcakend #
以下命令会在 /dev 下生成一个名为 bcache0 的 backend 设备
[root@pure-test ~]# make-bcache -B /dev/sda2
UUID: eaad4f10-2e58-4379-ba32-75deaa57eda0
Set UUID: 3246bd30-130d-4a5b-b1ff-e71fe37bedf4
version: 1
block_size: 1
data_offset: 16
backend 设备一旦正常生成,就可对其进行普通的格式化等操作,与操作普通硬盘分区一般
mkfs.ext4 /dev/bcache0
show real device #
查看此后端 bcache0 设备实际对应的实体磁盘
-
当 /dev/bcache0 未格式化文件系统时
[root@pure-test ~]# ls -lh /dev/bcache/by-uuid/ total 0 lrwxrwxrwx 1 root root 13 Sep 29 15:45 eaad4f10-2e58-4379-ba32-75deaa57eda0 -> ../../bcache0
可以看见此设备实际指向的是 uuid
eaad4f10-2e58-4379-ba32-75deaa57eda0
的设备[root@pure-test ~]# ls -lh /dev/disk/by-uuid/ total 0 lrwxrwxrwx 1 root root 10 Sep 29 15:38 388e01f1-a27c-4f6c-bcac-823962963259 -> ../../sda1 lrwxrwxrwx 1 root root 10 Sep 29 15:38 71683e71-2990-48a1-840d-0f43fb11340c -> ../../sda5 lrwxrwxrwx 1 root root 10 Sep 29 15:38 abeedced-9450-4159-927b-5b4298d96bc1 -> ../../sda3 lrwxrwxrwx 1 root root 10 Sep 29 15:38 bf8f710d-5c99-4d40-8747-00d72a5af2cf -> ../../sdb1 lrwxrwxrwx 1 root root 10 Sep 29 15:45 eaad4f10-2e58-4379-ba32-75deaa57eda0 -> ../../sda2 lrwxrwxrwx 1 root root 10 Sep 29 15:38 f1982595-8044-48ae-a344-54836d487666 -> ../../sda6 lrwxrwxrwx 1 root root 13 Sep 29 16:30 ff8e456b-a5a0-4d20-8697-241e451e486e -> ../../bcache0
可发现此 UUID 对应为 /dev/sda2
-
当 /dev/bcache0 已经格式化文件系统后
直接查看
/sys/block/bcache0/
[root@pure-test ~]# ls -lh /sys/block/bcache0/ total 0 -r--r--r-- 1 root root 4.0K Sep 29 10:53 alignment_offset lrwxrwxrwx 1 root root 0 Sep 29 10:53 bcache -> ../../../pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda2/bcache lrwxrwxrwx 1 root root 0 Sep 29 10:53 bdi -> ../../bdi/253:0 -r--r--r-- 1 root root 4.0K Sep 29 10:53 capability -r--r--r-- 1 root root 4.0K Sep 29 10:53 dev -r--r--r-- 1 root root 4.0K Sep 29 10:53 discard_alignment -r--r--r-- 1 root root 4.0K Sep 29 10:53 ext_range drwxr-xr-x 2 root root 0 Sep 29 10:53 holders -r--r--r-- 1 root root 4.0K Sep 29 10:53 inflight drwxr-xr-x 2 root root 0 Sep 29 10:53 power drwxr-xr-x 2 root root 0 Sep 29 10:53 queue -r--r--r-- 1 root root 4.0K Sep 29 10:53 range -r--r--r-- 1 root root 4.0K Sep 29 10:53 removable -r--r--r-- 1 root root 4.0K Sep 29 10:53 ro -r--r--r-- 1 root root 4.0K Sep 29 10:53 size drwxr-xr-x 2 root root 0 Sep 29 10:53 slaves -r--r--r-- 1 root root 4.0K Sep 29 10:53 stat lrwxrwxrwx 1 root root 0 Sep 29 10:53 subsystem -> ../../../../class/block drwxr-xr-x 2 root root 0 Sep 29 10:53 trace -rw-r--r-- 1 root root 4.0K Sep 29 10:53 uevent
可以看见此后端设备实际对应的是 /dev/sda2
backend 设备 bcache0 与一般硬盘表现看起来无异, 可通过常规的 UUID 查看法查看其 UUID
# 未格式化 /dev/bcache0 设备时, 设备是未拥有 uuid 的, 格式化后才拥有 uuid
[root@pure-test ~]# blkid
/dev/sda1: UUID="388e01f1-a27c-4f6c-bcac-823962963259" TYPE="ext4"
/dev/sda3: UUID="abeedced-9450-4159-927b-5b4298d96bc1" TYPE="ext4"
/dev/sda5: UUID="71683e71-2990-48a1-840d-0f43fb11340c" TYPE="ext4"
/dev/sda6: UUID="f1982595-8044-48ae-a344-54836d487666" SEC_TYPE="ext2" TYPE="ext3"
/dev/block/8:3: UUID="abeedced-9450-4159-927b-5b4298d96bc1" TYPE="ext4"
/dev/bcache0: UUID="ff8e456b-a5a0-4d20-8697-241e451e486e" TYPE="ext4"
[root@pure-test ~]# ls -lh /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Sep 29 15:38 388e01f1-a27c-4f6c-bcac-823962963259 -> ../../sda1
lrwxrwxrwx 1 root root 10 Sep 29 15:38 71683e71-2990-48a1-840d-0f43fb11340c -> ../../sda5
lrwxrwxrwx 1 root root 10 Sep 29 15:38 abeedced-9450-4159-927b-5b4298d96bc1 -> ../../sda3
lrwxrwxrwx 1 root root 10 Sep 29 15:38 bf8f710d-5c99-4d40-8747-00d72a5af2cf -> ../../sdb1
lrwxrwxrwx 1 root root 10 Sep 29 15:45 eaad4f10-2e58-4379-ba32-75deaa57eda0 -> ../../sda2
lrwxrwxrwx 1 root root 10 Sep 29 15:38 f1982595-8044-48ae-a344-54836d487666 -> ../../sda6
lrwxrwxrwx 1 root root 13 Sep 29 16:30 ff8e456b-a5a0-4d20-8697-241e451e486e -> ../../bcache0
eaad4f10-2e58-4379-ba32-75deaa57eda0
就是后端 HDD 存储 bcache0 的 UUID
one step #
可通过将一行指令同时生产 cacahe 和 backend 设备
make-bcache -B /dev/sda2 -C /dev/sdb1
指定相关参数
make-bcache --wipe-bcache -w512 --discard --writeback -B /dev/sda2 -C /dev/sdb1
attach & detach #
在 bcache-tools
编译安装时, 会安装相应的 udev rules, 会将 cache 设备与 backend 设备自动进行 attch (绑定).
相应的, 我们也可以进行手动 attch 或 detach
attach #
#attach
echo 5da393d6-b157-4bb3-a105-235a1425894d > /sys/block/bcache0/bcache/attach
即将 cache 设备的 UUID 写入到 backend (bcache0) 设备的 /sys/block/{设备}/bcache/attach
中
执行此命令后,会在 /sys/block/bcache0/bcache/
下生成一个 cache 目录 实际指向为 cache 设备目录 就表示已经 attch 成功
[root@pure-test ~]# ls -lh /sys/block/bcache0/bcache/
total 0
--w------- 1 root root 4.0K Sep 28 16:01 attach
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 bypass_torture_test
lrwxrwxrwx 1 root root 0 Sep 28 16:01 cache -> ../../../../../../../../../../../fs/bcache/5da393d6-b157-4bb3-a105-235a1425894d
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 cache_mode
--w------- 1 root root 4.0K Sep 28 15:13 clear_stats
--w------- 1 root root 4.0K Sep 28 16:01 detach
lrwxrwxrwx 1 root root 0 Sep 28 15:13 dev -> ../../../../../../../../../../virtual/block/bcache0
-r--r--r-- 1 root root 4.0K Sep 28 15:13 dirty_data
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 label
-r--r--r-- 1 root root 4.0K Sep 28 15:13 partial_stripes_expensive
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 readahead
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 running
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 sequential_cutoff
-r--r--r-- 1 root root 4.0K Sep 28 15:13 state
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_day
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_five_minute
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_hour
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_total
--w------- 1 root root 4.0K Sep 28 15:13 stop
-r--r--r-- 1 root root 4.0K Sep 28 15:13 stripe_size
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 verify
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_delay
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_metadata
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_percent
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate
-r--r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_debug
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_d_term
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_p_term_inverse
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_update_seconds
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_running
可以看见 cache 目录, 已经 attch 成功
detach #
#detach
echo 5da393d6-b157-4bb3-a105-235a1425894d > /sys/block/bcache0/bcache/detach
相应对于 attach, detach 成功之后 /sys/block/bcache0/bcache/
下的 cache 目录就会消失
[root@pure-test ~]# ls -lh /sys/block/bcache0/bcache/
total 0
--w------- 1 root root 4.0K Sep 28 16:01 attach
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 bypass_torture_test
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 cache_mode
--w------- 1 root root 4.0K Sep 28 15:13 clear_stats
--w------- 1 root root 4.0K Sep 28 16:01 detach
lrwxrwxrwx 1 root root 0 Sep 28 15:13 dev -> ../../../../../../../../../../virtual/block/bcache0
-r--r--r-- 1 root root 4.0K Sep 28 15:13 dirty_data
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 label
-r--r--r-- 1 root root 4.0K Sep 28 15:13 partial_stripes_expensive
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 readahead
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 running
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 sequential_cutoff
-r--r--r-- 1 root root 4.0K Sep 28 15:13 state
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_day
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_five_minute
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_hour
drwxr-xr-x 2 root root 0 Sep 28 15:13 stats_total
--w------- 1 root root 4.0K Sep 28 15:13 stop
-r--r--r-- 1 root root 4.0K Sep 28 15:13 stripe_size
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 verify
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_delay
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_metadata
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_percent
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate
-r--r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_debug
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_d_term
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_p_term_inverse
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_rate_update_seconds
-rw-r--r-- 1 root root 4.0K Sep 28 15:13 writeback_running
cache mode #
可以通过查看目录下的 cache_mode
文件来查看 cache 的缓存策略
[root@pure-test ~]# cat /sys/block/bcache0/bcache/cache_mode
writethrough [writeback] writearound none
修改策略
[root@pure-test ~]# echo writethrough > /sys/block/bcache0/bcache/cache_mode
[root@pure-test ~]# cat /sys/block/bcache0/bcache/cache_mode
[writethrough] writeback writearound none
强制让 backend 设备在无 cache 设备情况下运行
[root@pure-test ~]# echo 1 > /sys/block/sda/sda2/bcache/running
此处不能使用 /sys/block/bcache0
, 因为此时 bcach0 并不存在.
假如你的 backend 设备未使用分区, 则 bcache 目录为 /sys/block/sda/bcache
stop bcache #
停止 bcache
[root@pure-test ~]# echo 1 > /sys/block/sda/sda2/bcache/stop
bcache-status #
可以通查看 bcache 目录下的 state 文件来查看 bcache 的状态
cat /sys/block/bcache0/bcache/state
也可以通过 python 写的 bcache-status
小程序来查看 bcache 的状态 此工具包含在 fedora 20 以上的 bcache-tools
工具里, debian 系或自行编译的 bcache-tools
里并未有此工具, 需要自行上 github 下载.
[root@pure-test ~]# bcache-status --help
usage: bcache-status [--help] [-f] [-h] [-d] [-t] [-a] [-r] [-s] [-g]
optional arguments:
--help Show this help message and exit
-f, --five-minute Print the last five minutes of stats.
-h, --hour Print the last hour of stats.
-d, --day Print the last day of stats.
-t, --total Print total stats.
-a, --all Print all stats.
-r, --reset-stats Reset stats after printing them.
-s, --sub-status Print subdevice status.
-g, --gc Invoke GC before printing status.
这是正常 attach 后并有使用的状态, 可以看见 cache size, hits, cache mode 等详细信息
[root@pure-test ~]# bcache-status -a
--- bcache ---
UUID 5da393d6-b157-4bb3-a105-235a1425894d
Block Size 512 B
Bucket Size 512.00 KiB
Congested? False
Read Congestion 2.0ms
Write Congestion 20.0ms
Total Cache Size 28 GiB
Total Cache Used 6 GiB (23%)
Total Cache Unused 22 GiB (77%)
Evictable Cache 28 GiB (100%)
Replacement Policy [lru] fifo random
Cache Mode writethrough [writeback] writearound none
Last 5min Hits 0
Last 5min Misses 0
Last 5min Bypass Hits 0
Last 5min Bypass Misses 0
Last 5min Bypassed 0 B
Last Hour Hits 0
Last Hour Misses 0
Last Hour Bypass Hits 0
Last Hour Bypass Misses 0
Last Hour Bypassed 0 B
Last Day Hits 10 (55%)
Last Day Misses 8
Last Day Bypass Hits 0
Last Day Bypass Misses 0
Last Day Bypassed 0 B
Total Hits 95 (53%)
Total Misses 81
Total Bypass Hits 0
Total Bypass Misses 0
Total Bypassed 0 B
这是 detach 后的
[root@pure-test ~]# bcache-status -a
--- bcache ---
UUID 5da393d6-b157-4bb3-a105-235a1425894d
Block Size 512 B
Bucket Size 512.00 KiB
Congested? False
Read Congestion 2.0ms
Write Congestion 20.0ms
Total Cache Size 28 GiB
Total Cache Used 6 GiB (23%)
Total Cache Unused 22 GiB (77%)
Evictable Cache 28 GiB (100%)
Replacement Policy [lru] fifo random
Cache Mode (Various)
Last 5min Hits 0
Last 5min Misses 0
Last 5min Bypass Hits 0
Last 5min Bypass Misses 0
Last 5min Bypassed 0 B
Last Hour Hits 0
Last Hour Misses 0
Last Hour Bypass Hits 0
Last Hour Bypass Misses 0
Last Hour Bypassed 0 B
Last Day Hits 10 (55%)
Last Day Misses 8
Last Day Bypass Hits 0
Last Day Bypass Misses 0
Last Day Bypassed 0 B
Total Hits 95 (53%)
Total Misses 81
Total Bypass Hits 0
Total Bypass Misses 0
Total Bypassed 0 B
可以看见 Cache Mode (Various)
, 这表示 cache 设备已经 detach
补充 #
kernel doc 的描述: bcache.txt
archlinux 的 wiki