ディレクトリをsquashfsにしてアクセス速度を上げてみる

普段よくアクセスされるけれど、あまり変化が発生しないディレクトリってありますよね。/usrとか/optとかです。こういうディレクトリは、squashfsで圧縮して、それにアクセスするようにすると、HDDのIO速度 < 展開の速度のため、領域節約 & 速度アップという恩恵を得ることができます。
前々から、こうやると速くなるよ、というのは知っていたのですが、これまで中々できませんでした。そこで、色々なサイトを参考にして、/usrとか/optとかをsquashfsにしてみることにしました。(どのサイトを参考にしたかはメモってなかったため不明です・・・。参考にさせていただいたサイトの作者の方々に感謝します)

とりあえず私の環境です。

カーネル
2.6.32
ディストリ
Gentoo

これだけでとりあえず。CPUとかはあまり問題にならないような気がしています。

今回、/usrをsquashfs化しますが、それだけだと追加・更新ができません。これに対処するため、aufsという、unionfsの再実装(ということらしいです)を利用し、squashfs化したディレクトリに、書込み可能ディレクトリを被せます。が、私自身aufsがよくわかっていません。透過式のlayerみたいなもんなんだと解釈してます。

さて、さっそく準備ですが、まずはemergeしないとはじまりません。

emerge squashfs-tools aufs2

ですが、現時点(2010/1)では、aufs2はmaskされているため、installできないです。また、カーネルにパッチをあてる必要があるため、実際には以下のようになりました。

USE="kernel-patch inotify" ACCEPT_KEYWORDS="~x86" emerge aufs2

カーネルにパッチがあてられたため、カーネルを再構築しておいてください。で、とりあえず今回私の方針は以下のようにしました。

まず上から順にやっていきます。

mkdir /backup
cd /backup
mksquashfs /usr usr.squashfs
mksquashfs /opt opt.squashfs
mksquashfs /lib lib.squashfs

これで、現在の各ディレクトリのバックアップが取れました。次に、aufsに利用するためのディレクトリ群を作成します。

for d in "usr opt lib" do
mkdir -p /squash/$d
mkdir -p /squash/changed/$d
done

もちろん直接作成してもOKです。てかそっちの方が早いです。これで下準備はできました。ただ、aufs2をemergeした後、再起動してければ一回再起動します。
で、再起動後、起動時にマウントとかするために、/etc/fstabに以下を追記します。

/backup/usr.squashfs    /squash/usr             squashfs        ro,loop,defaults        0 0
/backup/opt.squashfs    /squash/opt             squashfs        ro,loop,defaults        0 0
/backup/lib.squashfs    /squash/lib             squashfs        ro,loop,defaults        0 0
none            /usr                    aufs            br:/squash/changed/usr=rw:/squash/usr=ro,noxino 0 0
none            /opt                    aufs            br:/squash/changed/opt=rw:/squash/opt=ro,noxino 0 0
none            /lib                    aufs            br:/squash/changed/lib=rw:/squash/lib=ro,noxino 0 0

aufsのオプションに、noxinoを指定していますが、私の環境ではなんでかこれを指定しないとエラーになりました。noxino無しでエラーが出ないようでしたら、外して問題無いと思います。

これで再起動すると、dfの結果が次のようになりました。(この結果で正しいのかはよーわかりません)

/dev/sda2      xfs    298G   73G  226G  25% /
udev         tmpfs     10M  184K  9.9M   2% /dev
shm          tmpfs    2.0G   59M  2.0G   3% /dev/shm
/dev/loop0
          squashfs    4.5G  4.5G     0 100% /squash/usr
/dev/loop1
          squashfs     58M   58M     0 100% /squash/opt
/dev/loop2
          squashfs     24M   24M     0 100% /squash/lib
none          aufs    298G   73G  226G  25% /usr
none          aufs    298G   73G  226G  25% /opt
none          aufs    298G   73G  226G  25% /lib

という形です。これで、/usrとかに新しくファイルが作成されると、/squash/changed/usrに変更が蓄積されていきます。ある程度変更が蓄積されたら、またsquashfsを再作成する必要があります。
その方法は確かちょっと違うのですが、まー当分は大丈夫かと思います。

とりあえずこんな感じで、成功しました。成功したら、一回/usr等にマウントされているものをumountして、/usrを/usr-oldとかにしておくとよいかと思います。削除すると後戻りができなくなるので、ディスクに余裕があるなら取っておいた方がいいと思います。