Flashcache
目次
イントロダクション
Flashcache は元々は Facebook (Mohan Srinivasan, Paul Saab, Vadim Tkachenko) によって開発され2010年4月にリリースされたモジュールです。ドライブのライトスルーキャッシュを他のドライブに保存することができるカーネルモジュールとなっています。性能を上げるために、回転ドライブをソリッドステートドライブにキャッシュするのによく使われています。ファイルをキャッシュすることで SSD 並みの速度と標準的な回転ドライブの容量の両方を教授できます。Facebook の開発目的はデータベースの I/O を高速化させることですが、どんな I/O でも簡単に対応可能です。
Flashcache の代替としては Bcache が存在します。
このドライバーは遅いドライブを速いドライブで高速化することを意図しているのをよく覚えてください。速いドライブは別にソリッドステートドライブである必要はありません。高速だが小容量な SCSI ドライブと大容量の SATA ドライブがある場合や、とても低速な "green" ドライブと超高速な 10k rpm ドライブがある場合など、様々な速度のドライブが複数存在するような状況で広く使うことができます。
インストール
カーネルモジュールの取得
現段階で Arch パッケージや AUR にはカーネルモジュールが含まれていないので、GitHub の https://github.com/facebook/flashcache から直接ファイルをダウンロードしてください。ダウンロードしたらイメージを展開してモジュール/ユーティリティをコンパイルします:
$ tar -xzvf facebook-flashcache-1.0-64-g085b7ba.tar.gz $ cd facebook-flashcache-085b7ba $ make KERNEL_TREE=<root of kernel source tree> (most likely in /usr/src)
コンパイルが完了したらモジュールをインストールしてください (インストールには root 権限が必要です):
# make KERNEL_TREE=<root of kernel source tree> install
そしてユーティリティを使いやすいように /usr/sbin
にコピーします:
# cp src/utils/{flashcache_create,flashcache_load,flashcache_destroy} /usr/sbin
速いドライブの準備
必要なキャッシュを行うための高速なドライブの準備をします。キャッシュのサイズに合わせてパーティションを作成してください。
flashcache の作成
# flashcache_create cached_part1 /dev/sdb1 /dev/sda3 # flashcache_create cached_part2 /dev/sdb2 /dev/sda4
ブート時にドライブを起動
flashcache をどう使うかによって設定は変わります。root ファイルシステムをキャッシュする場合、ブートの初期段階でドライブを起動し、/home
ドライブパーティションなどをキャッシュする場合は、ブートの後期でドライブを起動するようにします。ブートの後期でドライブを起動するほうが簡単です。
systemd を使ってブートの後期で起動
この方法では、systemd スクリプトを作成・有効化して flashcache モジュールをロードしてから flashcache ドライブをマウントします。
まず、/etc/fstab
を開いて /home
が UUID でマウントされるようになっていることを確認してください。そうなっていない場合は、/dev/disk/by-uuid
から UUID を取得して設定してください。Flashcache は flashcache ドライブにキャッシュ元と同一の UUID を設定するため、/etc/fstab
で UUID を使うことで flashcache ドライブがロードできなかった場合も起動することが可能になります。以下のようになっていれば問題ありません:
... UUID=5ebee55d-8871-44ea-b159-58c103970f54 /home ext4 rw,relatime ...
次に、実際に flashcache を利用する init スクリプトを作成します。
/lib/initcpio/hooks/flashcache
#!/bin/bash # Check if /home is mounted HOMEMOUNT=$(mount | grep home | sed 's/ .*//' | sed 's#.*/##' ) # Load module if not already loaded if [[ ! "$(eval lsmod | grep "^flashcache")" ]]; then modprobe flashcache fi # Mount flashcache /home if not already mounted if [[ ! "$HOMEMOUNT" == "cached_part2" ]]; then umount /home if [ ! -e /dev/mapper/cached_part2 ]; then flashcache_load /dev/sdb2 fi mount /home fi
そして init スクリプトを使うための systemd スクリプトを作成してください。
/lib/systemd/system/flashcache.service
[Unit] Description=FlashCache [Service] Type=oneshot RemainAfterExit=no ExecStart=/usr/local/bin/flashcache [Install] WantedBy=multi-user.target
最後に、以下のコマンドでサービスを有効化してください:
# systemctl enable flashcache
これで設定は完了です。
initcpio を使ってブートの初期に起動
この方法ではカーネルの初期 RAM ディスクを編集して flashcache をブートの初期段階でロードする必要があります。
RAM ディスクの設定
root パーティションを使用するようにキャッシュを設定する場合や、実行時にパーティションをアンマウントしたくない場合、RAM ディスクを変更して flashcache に対応して busybox で作業を行うのが一番です。キャッシュするファイルシステムがアンマウントされている場合、#他のファイルの変更までスキップしてください。
ここでは RAM ディスクを変更するベースとして LVM を使っていますが、別の方法もあります。まず、以下のファイルを作成 (ファイルの中身は適宜置き換えて下さい):
/lib/initcpio/hooks/flashcache
# vim:set ft=sh: run_hook () { /sbin/modprobe -q dm-mod >/dev/null 2>&1 if [ -e "/sys/class/misc/device-mapper" ]; then if [ ! -e "/dev/mapper/control" ]; then /bin/mknod "/dev/mapper/control" c $(cat /sys/class/misc/device-mapper/dev | sed 's|:| |') fi [ "${quiet}" = "y" ] && LVMQUIET=">/dev/null" msg "Activating cache volumes..." eval /usr/sbin/flashcache_load cached_part1 /dev/sdb1 /dev/sda3 $LMQUIET eval /usr/sbin/flashcache_load cached_part2 /dev/sdb2 /dev/sda4 $LMQUIET fi }
/lib/initcpio/install
# vim: set ft=sh: install () { MODULES="dm-mod" BINARIES="" FILES="" SCRIPT="flashcache" add_dir "/dev/mapper" add_binary "/sbin/dmsetup" add_binary "/usr/sbin/flashcache_create" add_binary "/usr/sbin/flashcache_load" add_binary "/usr/sbin/flashcache_destroy" add_file "/lib/udev/rules.d/10-dm.rules" add_file "/lib/udev/rules.d/13-dm-disk.rules" add_file "/lib/udev/rules.d/95-dm-notify.rules" add_file "/lib/udev/rules.d/11-dm-lvm.rules" } help () { cat<<HELPEOF This hook loads the necessary modules for a flash drive as a cache device for your root device. HELPEOF }
/etc/mkinitcpio.conf
を更新:
モジュールに flashcache を追加:
MODULES="flashcache"
フックに flashcache を追加 (ファイルシステムの前に追加するようにしてください):
HOOKS="... flashcache ..."
そして ramdisk イメージを再生成:
# mkinitcpio -g /boot/<your ramdisk filename>.img
通常のイメージとは別の ramdisk イメージを作成して、grub の設定ファイルに新しいエントリを追加して作成した ramdisk を使うようにすることも可能です。
他のファイルの変更
新しいパーティションが /dev/mapper
に出現するので元の /dev/sd*
パーティションの代わりに新しいパーティションをマウントしてください。GRUB と fstab を編集して新しいパーティションをマウントする必要があります。以下の例では、root パーティションは /dev/mapper/cached_part1
でホームディレクトリは /dev/mapper/cached_part2
となっています。
/boot/grub/menu.lst
# (0) Arch Linux title Arch Linux(flashcache) root (hd0,0) kernel /vmlinuz26 root=/dev/mapper/cached_part1 ro 5 initrd /kernel-2.6.38.4.img
/etc/fstab
... /dev/mapper/cached_part1 / ext3 defaults 0 1 /dev/mapper/cached_part2 /home ext3 defaults,user_xattr 0 1 ...
root パーティションをキャッシュする場合、再起動して grub で e を押してカーネルコマンドラインのオプションを編集してください。カーネルオプションの行を選択したら再度 e を押します。'break=y' をクォートで囲まずに末尾に追加してエンターを押してください。b を押すと起動します。これでモジュールがロードされた後に RAM ディスクが停止してシェルが起動するので作業をすることができます。
(flashcache ramdisk を使用していることを確認したら) 再起動してマウントされたパーティションが新しく作成したパーティションであることを確認してください。
設定
キャッシュを制御するための多くのオプションが存在します。flashcache のドキュメントにあるシステム管理者ガイドを確認してください。例えば /etc/sysctl.d/90-flashcache.conf
に以下の設定を追加します:
##################### # flashcache settings ##################### # disable writing dirty cache data at shutdown dev.flashcache.fast_remove = 1 # change the reclaim policy to LRU from FIFO dev.flashcache.reclaim_policy = 1 # do not write "stale" data to disk until evicted due to lack of space dev.flashcache.fallow_delay = 0
トラブルシューティング
- キャッシュを作成しようとすると
device-mapper: reload ioctl failed: Invalid argument
というエラーが表示される場合、マウントしたファイルシステムのキャッシュを作成してみてください。 - 起動が失敗する場合、GRUB のカーネルコマンドラインに
break=y
を追加して RAM ディスクのシェルを使うことで簡単にキャッシュの確認ができます。 - キャッシュが上手く使われないときは
/proc/flashcache_stats
に役に立つ情報が含まれているはずです。
参照
- オリジナルのアナウンス - http://www.facebook.com/note.php?note_id=388112370932
- Github ソース - https://github.com/facebook/flashcache