目次
概要
今回は、HDDなどの比較的低速なブロックデバイスに対して、SSDなどの比較的高速なブロックデバイスをキャッシュとして使える bcache をセットアップ方法と各種設定などについて紹介します。
bcacheとは
bcacheは、ブロックデバイスをキャッシュとして使うための仕組みを提供するソフトウェアです。
bcacheでは、キャッシュとして使用するブロックデバイスを キャッシュデバイス
と呼び、データを保存する為のブロックデバイスを バッキングデバイス
と呼びます。
似たような仕組みを提供するソフトウェアとしてLVM cacheやdm-cacheなどがありますが、bcacheの方がセットアップが容易だったり性能が高いという特徴があります。
キャッシュがあることのメリット
通常、高速なIO性能を必要とするシステムにおいてはHDDではなく高速なSSDをストレージとして利用します。
しかし、SSDはHDDに比べると容量単価が高く、大容量のストレージが必要な場合にはコストが大きな問題となります。
そこで登場するのがキャッシュです。
例えば、データへのアクセスの性質が「書き込んだばかりのデータを読み取ることが多い」場合や「同じデータに頻繁にアクセスすることが多い」場合、全てのデータ領域において高速にアクセスできる必要性はなく、アクセス頻度の高いデータのみ高速にアクセス出来ればほとんど問題ないといえます。
つまり、アクセス頻度の高いデータのみ高速なブロックデバイス上にキャッシュしておけばいいわけです。
高価なRAIDコントローラなどではより高速にアクセス可能な揮発性メモリを使用したキャッシュが搭載されており、書き込みなどをキャッシュすることで高速なストレージアクセスを実現しています。
キャッシュの種類
キャッシュにはいくつかのモードがあります。
- writeback
- 書き込まれたデータはまずキャッシュデバイスに書き込まれ、その次にバッキングデバイスへ書き込まれます。しかし、書き込みが完了したとみなされるのはキャッシュデバイスに書き込まれた後であり、その後非同期的にバッキングデバイスへ書き込まれます。
- writethrough
- 書き込まれたデータはキャッシュデバイス及びバッキングデバイスへ同時に書き込まれ、バッキングデバイスへの書き込みが完了した時点でIOが完了したとみなされます。そのため、writebackより安全性が高いですがパフォーマンス面では劣ります。
- writearound
- 読み取り専用のキャッシュモードです。書き込まれたデータは直接バッキングデバイスへ書き込まれます。キャッシュデバイスへは書き込まれないため、書き込み操作ではキャッシュデバイスの恩恵を受けることはできません。また、データが読み取られるとき、初回はバッキングデバイスから読み取りキャッシュします。このモードのメリットは書き込みをキャッシュしないためキャッシュデバイスの寿命を向上させることができる点です。
- none (bcache)
- bcacheは何もしません。
通常はwritebackを使用すれば問題ないはずです。
安全性を重視する場合はwritethroughを、Read intensive(読み取りメイン)な場合はwritearoundを使用すれば良いでしょう。
bcacheをセットアップする
今回は、Ubuntu 22.04 環境下でセットアップを行います。
本例では /dev/sdb
をバッキングデバイスとして使用し、キャッシュデバイスは /dev/nvme0n1
を使用しています。
なお、キャッシュデバイス及びバッキングデバイスともにパーティションを含めた既存のデータはすべてロストします。
念のため、使用するブロックデバイスを初期化しておきます。下記のいずれかのコマンドを実行すれば十分でしょう。
必要に応じてブロックデバイスのパスは変更してください。
# dd if=/dev/zero of=/dev/sdb bs=1M count=1000
# sgdisk -Z /dev/sdb
bcacheを使用するために必要な bcache-tools
をインストールします。
# apt update
# apt install bcache-tools
続いて、bcacheデバイスを作成します。-B
オプションの後に指定したブロックデバイスはバッキングデバイスとして使用され、 -C
オプションの後に指定したブロックデバイスはキャッシュデバイスとして使用されます。
# make-bcache -B /dev/sdb -C /dev/nvme0n1
make-bcache
コマンドの実行後、 bcache0
デバイスがシステムに認識されているはずです。
# ll /sys/block/ | grep bcache
lrwxrwxrwx 1 root root 0 Feb 7 14:47 bcache0 -> ../devices/virtual/block/bcache0/
あとは通常のブロックデバイスと変わらずに使用することができます。
ここでは一般的な mkfs
などでファイルシステムを作成しマウントする方法を紹介しておきます。
# mkfs.ext4 /dev/bcache0
# mkdir /mnt/bcache-device
# mount /dev/bcache0 /mnt/bcache-device
なお、必要に応じて /etc/fstab
にマウント設定を追記しておくと良いでしょう。
設定を変える
- キャッシュデバイスの状態を確認する
# bcache-super-show /dev/nvme0n1
sb.magic ok
sb.first_sector 8 [match]
sb.csum E200784837EB4188 [match]
sb.version 3 [cache device]
dev.label (empty)
dev.uuid d7be4216-fac7-4bb5-8090-3d85d06374c1
dev.sectors_per_block 1
dev.sectors_per_bucket 1024
dev.cache.first_sector 1024
dev.cache.cache_sectors 1953523712
dev.cache.total_sectors 1953524736
dev.cache.ordered yes
dev.cache.discard no
dev.cache.pos 0
dev.cache.replacement 0 [lru]
cset.uuid 090c7c50-5680-46f2-97b0-fc075eaea7c2
- バッキングデバイスの状態を確認する
# bcache-super-show /dev/sdb
sb.magic ok
sb.first_sector 8 [match]
sb.csum C01EF4DC00D547BF [match]
sb.version 1 [backing device]
dev.label (empty)
dev.uuid cc268d3d-6044-4a37-be79-2d8fea765093
dev.sectors_per_block 1
dev.sectors_per_bucket 1024
dev.data.first_sector 16
dev.data.cache_mode 0 [writethrough]
dev.data.cache_state 1 [clean]
cset.uuid 090c7c50-5680-46f2-97b0-fc075eaea7c2
- キャッシュモードを確認する
# cat /sys/block/bcache0/bcache/cache_mode
[writethrough] writeback writearound none
- キャッシュモードを変更する
# echo writethrough | sudo tee /sys/block/bcache0/bcache/cache_mode
補足
fioなどのストレージベンチマークツールでは、bcacheのキャッシュ効果を正しく確認できない場合があります。
理由としては、fioのテストデータは単一ファイルとして生成されるため、シーケンシャルな書き込みとみなされキャッシュされないためです。
これは、シーケンシャルなアクセスを全てキャッシュデバイスに書き込んでいると、キャッシュデバイスの寿命を大幅に縮めることになるからです。
bcache上では特定のサイズ以上のIOをキャッシュしないように設定されており、デフォルトでは4.0MBになっています。
この設定は変更することができ、0に設定することで全てのIOをキャッシュすることができるようになります。
- キャッシュデバイスへの書き込みをやめるサイズを確認・変更する
# cat /sys/block/bcache0/bcache/sequential_cutoff
4.0M
# echo 0 | sudo tee /sys/block/bcache0/bcache/sequential_cutoff
まとめ
今回は、SSDを高速なキャッシュデバイスとして使用できる仕組みであるbcacheのセットアップ方法を紹介しました。
手順が非常に簡単でありセットアップしやすい点に加えて、類似したソフトウェアであるLVM cacheなどと比較してパフォーマンスが良いという利点があります。
詳細なパフォーマンステスト結果は、気が向けば書き起こしたいと思います。
既存のストレージ環境に導入することはできませんが、新たにストレージを用意する場合などで導入を検討してみると良いかもしれません。