今回はLinuxカーネルのブロック層キャッシュ、bcacheを紹介します。
NASとbcache
第851回では、SMBサーバー実装としてKSMBDを紹介しました。
そのときは10GbEを使用しており、速度もそれなりに出ていましたが、テスト用ということで共有フォルダーはNVMe SSD上に作成していました。
NVMe SSDは、2TBであればそれなりに手出しできる価格ですが、NASとして使用するストレージで2TBというのは少々心許ないといっていいでしょう。4TBとなると3〜4万円となり、なかなか手を出すのが難しくなってきます。8TBであればなおさらです。
ではHDDはというと、容量あたりの価格はSSDよりもはるかに安いものの、速度は文字どおり桁違いに遅くなります。せっかくの10GbEが活かせません。
用途にもよりますが、頻繁に読み書きするものの、あまり大きなファイルを置かないストレージをSSDにします。バックアップのような大容量を使用し、書き込みはするもののあまり読み込まないストレージをHDDにすれば、コストパフォーマンスのいいNASになります。
しかし、ここでネックになるのは前述のようにHDDの書き込みの遅さです。この解決のために、SSD上にキャッシュ領域を設けることを考えました。
そこで見つけたのがbcacheです。まさに期待したとおりのものであり、かつ歴史もあって不具合に遭遇することもそうはなさそうです。ファイルシステムで冒険する度胸は、筆者にはありません。SSDに専用のキャッシュ領域を用意するのはわかりますが、HDDもフォーマットし直さなければいけないというのがネックではあるものの、そこがどうにかなるのであれば有用そうです。
具体的な用途としては、Clonezillaのバックアップ置き場を想定しています。バックアップをアーカイブイメージとして作成しているアプリケーション
HDDに書き込んだ場合
今回は6TB HDDを用意し、ここに適当なフォルダーを作成し、KSMBDで共有します。まずはリファレンスとしてベンチマーク結果を見てみましょう。10GBのファイルを3回転送しています。

10GbEは理論上1250MB/
bcacheの設定
では、bcacheを設定していきます。
おさらいになりますが、前提としては専用のSSDとHDDが必要になります。ただし、パーティションでも構いません。用途的には、SSDにはUbuntuとbcacheのパーティションを作成し、HDDは専用となるケースが多いでしょうか。
というわけで、インストールの時点でbcache用のパーティション領域を用意しておきましょう

実際にはキャッシュ領域に500GBはいささか多すぎるので、例えば容量の小さなNAS向けSSDを購入するのもいいでしょう。キャッシュ領域は100GBもあれば充分かと思われます。
設定方法はUbuntu Wikiにかかれているものを参考にします。
パーティションは次のとおりです。
- システムパーテション:/dev/
nvme0n1p2 - SSDキャッシュパーティション:/dev/
nvme0n1p3 - HDD:/dev/
sda
繰り返しになりますが、キャッシュパーティションとHDDはフォーマットされます。すなわち、すべてのデータが消えますので、くれぐれも気をつけください。
作業を続行する決意ができたら、端末から次のコマンドを実行してください。
$ sudo apt install bcache-tools $ sudo dd if=/dev/zero if=/dev/nvme0n1p3 bs=512 count=8 $ sudo dd if=/dev/zero if=/dev/sda bs=512 count=8 $ sudo wipefs -a /dev/nvme0n1p3 $ sudo wipefs -a /dev/sda $ sudo make-bcache -C /dev/nvme0n1p3 -B /dev/sda --discard --writeback $ sudo mkfs.ext4 /dev/bcache0 $ sudo mkdir /media/hdd $ sudo sh -c "/dev/disk/by-uuid/(UUID) /media/bcache ext4 rw 0 0 >> /etc/fstab"
今回作成したHDDのパーティションのUUIDは"8c9c8369-f175-43ea-9ae2-3632d7e7d068"でした。mkfs.
$ sudo mkfs.ext4 /dev/bcache0/bcache0 mke2fs 1.47.0 (5-Feb-2023) Discarding device blocks: done Creating filesystem with 1465130644 4k blocks and 183144448 inodes Filesystem UUID: 8c9c8369-f175-43ea-9ae2-3632d7e7d068 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848, 512000000, 550731776, 644972544 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done
/media/

いい感じの速度になりました。
パフォーマンスのチューニング
今一度bcacheの設定コマンドを見てみます。
$ sudo make-bcache -C /dev/nvme0n1p3 -B /dev/sda --discard --writeback
bcacheには4つのキャッシュモードがあり、ここでは"writeback"モードを指定しています。それぞれ見ていきましょう。
- writeback:一度キャッシュに書き込み後、非同期にHDDと同期する。特徴上一番高速だが、HDDに書き出す前に電源が切れるとデータが失われる
- writethrough:キャッシュとHDDに同時に書き込み、HDDに書き込み完了後キャッシュから消える。安全だが速度は出ない
- writearound:書き込みにキャッシュを使用しない。読込時のみに使用する。SSDの書き込みを減らすためのモード
- none:キャッシュを使用しない
正直なところ"writeback"モードを使用しないのであれば、bcacheを使用する意味がないといっていいでしょう。たくさん書き込める
またbcacheのドキュメントによると、
$ echo 0 |sudo tee /sys/block/bcache0/bcache/sequential_cutoff
を実行すれば、あらゆるファイルに関してキャッシュが効くようになります。
"sequential_
ドキュメントには他のパラメーターも紹介されていますが、今回のような用途では制限に引っかかることはないと思われるため、紹介を省略します。
/sys/以下に書き込んだ場合、再起動すると設定が消えてしまうので、永続化したい場合は次のようなコマンドを実行します。
$ echo "w /sys/block/bcache0/bcache/sequential_cutoff - - - - 0" | sudo tee /etc/tmpfiles.d/bcache.conf