Linux 高速化: /usr を圧縮して読み込み速度を上げる. squashfs & aufs

概要

PCの動作は速いほうが良いに決まっている.

速度低下の原因は何か?大きく分けて2つある.

CPU(計算)が遅いか,IO(HDDへの読み書きなど)が遅いか.

PCを実際に使用して気づくことがある.

CPUが力不足で遅くなることよりも,IOのほうが足を引っ張る事が多い(個人的経験と偏見,モバイルPCとかだと違うかもしれない).

故に,PCの動作を速くしたいなら,IO性能の向上を目論むべき.

自分が知っているのは3つの方法.

1) 高性能なSSDを使う(だが,値段が高い).

2) 爆速なRAMを有効活用する(tmpfsなど).

3) データを圧縮して保存しおく.読み込むべき量が減るので読み込みは速くなる.その分,展開にCPUを消費する.

Linux上で3を実現する.

使うのは squashfs と aufs.

squashfs は読み込み専用だが,圧縮したデータをあたかも,圧縮していなように見せてくれる.

この読み込み専用ディレクトリの上に通常の読み書き可能なディレクトリを被せるのが,aufs.

外から見ると単一の読み書き可能ディレクトリに見える.また,データは圧縮されているので,読み込み量は通常よりも少なくて済む.

これが利点.

欠点.読み込み時に展開が必要でCPUを食う.データの変更は通常ディレクトリに書き込まれる.

つまり,長く使用していると,折角,圧縮した効果がほぼ消失する.よって,たまにsquashfsを

再構成する必要がある.

参考

gentooのフォーラムにはベンチマークの結果がある.

30%ぐらいパフォーマンスが向上したという,

注意

あたなのシステムを破壊する可能性があります.

ここに書いてあることを実行して,PCが起動しなくなったとしても,

多分,だれも助けてくれません.

少なくとも僕は助けられそうにありません.

環境

  • ArchLinux (i686)
  • kernel 2.6.32.2
  • /usr 4.9G

必要なものをインストール.

sudo pacman -S squashfs-tools aufs2

他のディストリビューションでも,ほとんど同じだと思う.

step 1: make squashfs file

sudo mkdir -p /squash/usr/{ro,rw}
sudo mksquashfs /usr /squash/usr/usr.sqfs

mksquashfsは結構時間がかかります.

ちなみに 4.9G から 2.0G に圧縮されました.

step 2: edit /etc/fstab

/squash/usr/usr.sqfs /squash/usr/ro squashfs loop,ro 0 0
usr /usr aufs br:/squash/usr/rw:/squash/usr/ro 0 0

(必要はない→)再起動して,正常かどうかチェックする.

(念の為)

todo

aufsのマウントオプションについて調べる.

http://forums.gentoo.org/viewtopic-t-646289.htmlには udba=reval のオプションが追加してあった.

一方,http://ubuntuforums.org/showthread.php?t=778355には udba は無し.

UDBAの解説は↓にある.しかし,読んでも理解できなかった.

http://www.linuxcertif.com/man/8/mount.aufs/#User%27s_Direct_Branch_Access_(UDBA)_276784h

ただ,

  • udba=none:最速,しかし,危険.普通は選択しない.
  • udba=reval:標準設定.安全性と速度を両立.
  • udba=inotify:遅くなるかもしれない.必要になったら,remountとして再設定推奨.

みたいなことが書いてあった.

ということで,デフォルトを選択.つまり,udbaオプションは記述しない.

step 2.5: edit /etc/rc.shutdown (追記)

このまま普通にシャットダウンすると,ファイルシステムをアンマウントするとき,デバイスがbusyだと怒らることがあります(シャットダウンはできる).

これは,aufsのxinoという機能がファイルシステムを使用しているため(アンマウントしても使用しているみたい).

参考:http://aufs.sourceforge.net/aufs.html#External%20Inode%20Number%20Bitmap,%20Translation%20Table%20and%20Generation%20Table%20(xino)

そこで,/etc/rc.shutdownを編集します.

stat_busy "Unmounting Filesystems"
/bin/umount -a -r -t noramfs,notmpfs,nosysfs,noproc -O no_netdev
stat_done

となっているものを

stat_busy "Unmounting Filesystems"
/bin/mount -n -o remount,ro,noxino /usr
/bin/umount -l /usr
/bin/umount -l /squash/usr/ro
/bin/umount -a -r -t noramfs,notmpfs,nosysfs,noproc -O no_netdev
stat_done

と編集する.

step 3: remove /usr

圧縮前の/usr は正に無用の長物なので,削除する.

sudo umount -l /usr
sudo mv /usr /usr-old
/squash/usr/ro/bin/sudo mkdir /usr
/squash/usr/ro/bin/sudo mount /usr

なにかおかしくなったら,/squash/usr/ro/bin/sudo mv /usr-old /usr で変更をもとに戻す.

sudo ではなく /squash/usr/ro/bin/sudo なのは,/usr がアンマウントされ,しかも,リネームされてしまったから.

問題なければ,/usr-old も消去する.

ただし,失敗すると後戻りはできないので慎重に.

注意

http://forums.gentoo.org/viewtopic-t-646289.htmlより,

WARNING: DON’T delete the original folder contents of the /lib folder after compressing it. Its contents are needed by the mount.aufs utility itself. If you delete it, you will get a broken system and will need a LIVECD to repair things. Just mount the aufs /lib over the initial /lib folder. You will waste a bit of disk space this way, but you will still get the speed increase, and you are going to be safer. As a matter of fact, any folder that is small enough to begin with (/bin /sbin /lib ) should be treated the same.

同様の方法で,/lib も圧縮できる.しかし,圧縮後もオリジナルのディレクトリは削除するな.mount.aufsに必要なものが含まれているから.削除すると,ライブCD等での復旧が必要になるだろう.ディスク容量は食うが,速度は速くなるし,安全だ./bin, /sbin についても同様.

まあ,要するに,/bin, /sbin, /lib は削除squashfsで圧縮するなってことだ.

step 4: reconstruct squashfs

/usr の変更は /squashgs/usr/rw に蓄積される.時間が経つとこのディレクトリが大きくなってくるかもしれない.そういときは,squashfsをつくりなおせば良い.

mksquashfs /usr /squash/usr/usr_new.sqfs
umount -l /usr
umount -l /squash/usr/ro
rm /squash/usr/usr.sfs
mv /squash/usr/usr_new.sqfs /squash/usr/usr.sqfs
rm -rf /squash/usr/rw/*
mount /squash/usr/ro
mount /usr

シェルスクリプトにしておくと便利かもしれない.

結果

/usrの他に,/opt, /lib, /bin, /sbinも圧縮した.正直後ろ2つは,効果無いのではと,疑っている(もともと小さいから).

圧縮結果

/usr 4.9G → 2.0G

/opt 2.6G → 816M

/lib 141M → 47M

/bin 4.6M → 2.2M

/sbin 14M → 5.7M

速度

OpenOfficeを起動してみたら,明らかに速くなっていた.

たぶん起動時間は2/3程度になったのではないだろうか.

保守

ただ定期的にsquashfsを再構成しなくていは,いけない.

スクリプトでも書いて,crontabが簡単な方法か?

追記

/lib, /bin, /sbinなどをsquashfsで圧縮した場合カーネルアップデートのときに面倒になる.

これらのファイルは起動時に必要になるので,/lib, /bin, /sbin を削除してはいけないと上で述べた.

それに加えて,起動時に必要なもの,カーネルのモジュール(とくに,aufs,squashfs関係)などが,/squash/lib/rwではなく/libにないといけない.それらが無いと,aufs,squashfsをマウントできない.

よって,カーネルをアップデートしたら,/squash/lib/rwと同時に起動時に読まれる/libも更新しないと,まずい.これは面倒だ.

という理由から現在はsquashfs,aufsを利用しているのは/usr, /optだけ.

More Reading
Newer// 一言日記