bcacheのユーザインターフェイスは破綻している. どうしてwriteboostのように美しいものが拒絶されて, bcacheのように汚いものがマージされるのかが全く理解出来ない. OSSも所詮政治か. Googleのやつが作ったらうんこだって受け入れるのがLinuxカーネルか. だとしたら絶望する.
bcacheを利用するためには二つのディスク(backing device, cache device)が必要である. これらのデバイスを管理するマンがいて, そいつに対してsysfsやbcache-toolsを通じてお願いをする. 管理とはここでは, bcacheに使うに当たっての登録(register/unregister)とか, backingとcacheの結合(attach/detach)などである.
dm-writeboostをdm-lcの時代から追ってきたみなさんなら分かるだろうが, これはlc-adminの思想と極めて似ている. lc-adminは, lc-mgrというターゲットであり, こいつに対してmessageでお願いをして(実際にはそのラッパーであるPythonプログラムを経由する), キャッシュの挙動はsysfsで行うというものである. この設計は, kernelvmでも話した通り, dmのメンテナによって否定され, device-mapperターゲットとして正しい実装に変更した経緯がある.
- bcacheを使うためには, bcache-toolsを入れる必要がある. Githubから落としてきてインストールすればよい.
- make-bcacheを使って, 利用するデバイスの初期化を行う必要がある. ここで, 公式(http://bcache.evilpiepirate.org/)にあるように
make-bcache -C xxx -B yyy
の使い方をすれば, backingとcacheのattachまで自動的にやってくれる. make-bcacheしたあと, backing一つに対して/dev/bcacheNというのが割り当てられ, cacheに対しては/sys/fs/bcache以下に羅列されるUUIDが割り当てられる. この状態で, UUIDをbcacheNに対してattachという設計思想であると思う. - この時点で/dev/bcache0を使うことが出来る.
この状態で, lsblkをすると, 以下のようになる. vdd1がbackingで, vdd2がcacheである.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| root@Hercules:/home/akira/dm-writeboost# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 254:0 0 39.1G 0 disk
├─vda1 254:1 0 37.4G 0 part /
├─vda2 254:2 0 1K 0 part
└─vda5 254:5 0 1.6G 0 part [SWAP]
vdb 254:16 0 20G 0 disk
├─vg1-cache3m (dm-1) 252:1 0 4M 0 lvm
└─vg1-cache2g (dm-2) 252:2 0 2G 0 lvm
vdc 254:32 0 60G 0 disk
└─vdc1 254:33 0 20G 0 part
└─vg2-back18g (dm-0) 252:0 0 18G 0 lvm
vdd 254:48 0 9.8G 0 disk
├─vdd1 254:49 0 3G 0 part
│ └─bcache0 253:0 0 3G 0 disk
└─vdd2 254:50 0 1G 0 part
└─bcache0 253:0 0 3G 0 disk
|
sysfsを通じて, デバイスのチューニングや統計取得を行うことが出来る.
cache_modeはwriteback, writethrough, writearoundが選択出来る(defaultは安全サイドに振ってwritethrough). 驚くのは, cache_modeがbackingの設定になっていることである. bcacheは複数backingがcacheをシェアすることを許している(これもdm-lcの思想だったが否定された. この点からもdm-lcとbcacheはユーザインタフェイスの点ではかなり近かったと言える)のだが, 各backingが異なるcache_modeを選択してきたらどうするつもりだろうか. 原理的にはもしかしたら, backingの設定によってキャッシュ制御を分岐することも可能だと思う(もっとも厳しいwritebackで動くならば混在可能である可能性は高い)が, 制御の分岐とか待ちとか, あるbackingがwritebackを選択することを汲んだ妥協が必要になるというのが私の直感である. そんな妥協をしてまでサポートする仕様であるとは到底思えない.
1
2
3
4
5
6
7
8
9
10
| root@Hercules:/home/akira/dm-writeboost# ls /sys/block/vdd/vdd1/bcache
attach detach partial_stripes_expensive state stats_total writeback_metadata writeback_rate_d_smooth writeback_running
cache dev readahead stats_day stop writeback_percent writeback_rate_d_term
cache_mode dirty_data running stats_five_minute stripe_size writeback_rate writeback_rate_p_term_inverse
clear_stats label sequential_cutoff stats_hour writeback_delay writeback_rate_debug writeback_rate_update_seconds
root@Hercules:/home/akira/dm-writeboost# ls /sys/block/vdd/vdd2/bcache/
block_size cache_replacement_policy freelist_percent nbuckets written
btree_written clear_stats io_errors priority_stats
bucket_size discard metadata_written set/
|
bcacheは再起動後にも自動的にbcacheを再構成してしまうため, 測定などでリセットしたい場合はunregisterとstopが必要となる. 終了処理についてはここが詳しいと思う(http://pommi.nethuis.nl/ssd-caching-using-linux-and-bcache/). unregisterは, cacheデバイスをdetachして抹消すること(registerとunregisterの動作が対称になってないように思う. だとすると素人設計である. リソースリーク回避のために余計なコードが必要にある可能性が高い). stopはbackingへのI/O可能性を完全に断つこと, なぜかbcacheNも削除される.
EnhanceIOはbcacheの性能測定を行っており, その設定スクリプトが公開されているので, これを読めばbcacheの使い方自体は理解出来るだろうと思う(https://github.com/stec-inc/EnhanceIO/blob/master/performance_test/bcache.sh).
以上, 朝からbcacheの調査を始めてあまりのファッキンさに4時間くらい苦労したためメモを残す. 実は, まだちゃんと測定をしていないため, この設計で本当に正しく動いてるのかわからない. bcacheなんかやめてみんなwriteboostを使えばいいよ. writeboostのユーザが増えてきたら, readboostの開発を開始してもいい.
作成/破棄スクリプトをうp
交互に実行して正常に動いているようなので正常に動いてるのだと思う.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| . ./config
echo discard
# /usr/local/util-linux/sbin/blkdiscard --offset 0 --length `blockdev --getsize64 ${CACHE}` $CACHE
echo wipe backing fs
wipefs -a $BACKING
echo run make-bache
make-bcache -B $BACKING -C $CACHE --wipe-bcache
# Getting rid of these two registering lines
# results in not finding the sysfs for the cache device.
# As to the slowness of udev recognizing the device.
# is it async? (meaning run in background)
echo $BACKING > /sys/fs/bcache/register
echo $CACHE > /sys/fs/bcache/register # 排除するとうまくいくline (後述)
echo set writeback
echo writeback > /sys/block/vdd/vdd1/bcache/cache_mode
lsblk -o NAME,MAJ:MIN,RM,SIZE,TYPE,FSTYPE
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ./config
# Stopping the bcache device must take precedence
# over unregistering caches. Otherwise, system halts.
echo 1 > /sys/block/vdd/vdd1/bcache/stop
# We can get the bcache UUID by cutting
# the output of bcache-super-show but
# it is too much here. we can remove all the
# cache devices in the benchmarking.
for d in /sys/fs/bcache/* # * :: UUID
do
un=$d/unregister
if [ -f $un ]; then
echo unregister $un
echo 1 > $un
fi
done
|
生成スクリプトを実行した時のdmesgが以下
errorが出ているのが気になるが, 問題だろうか?どうも動作が読めないが, これ以上何かやることあるのかな. CACHEの方のregisterを排除するとエラーなく動くようになる. 理由は分からんがそれで良い?
1
2
3
4
5
6
| root@Hercules:/home/akira/dm-writeboost# dmesg
[ 559.072210] bcache: register_bdev() registered backing device vdd1
[ 559.073941] bcache: run_cache_set() invalidating existing data
[ 559.224841] bcache: bch_cached_dev_attach() Caching vdd1 as bcache0 on set 836d9857-1fb7-4a24-8c7a-4b31d66e3d44
[ 559.224863] bcache: register_cache() registered cache device vdd2
[ 559.224886] bcache: register_bcache() error opening /dev/vdd2: device already registered
|
最小単位の修正(コンパイル通すだけ)だが, bcache-toolsへのプルリクがマージされた(https://github.com/g2p/bcache-tools/pull/5). これでおれもbcache familyだぜ.