テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

bcacheの使い方

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ターゲットとして正しい実装に変更した経緯がある.

  1. bcacheを使うためには, bcache-toolsを入れる必要がある. Githubから落としてきてインストールすればよい.
  2. 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という設計思想であると思う.
  3. この時点で/dev/bcache0を使うことが出来る.

この状態で, lsblkをすると, 以下のようになる. vdd1がbackingで, vdd2がcacheである.

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を選択することを汲んだ妥協が必要になるというのが私の直感である. そんな妥協をしてまでサポートする仕様であるとは到底思えない.

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
交互に実行して正常に動いているようなので正常に動いてるのだと思う.

. ./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
 ./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を排除するとエラーなく動くようになる. 理由は分からんがそれで良い?

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だぜ.