2013年6月29日土曜日

zfs-fuse を使って CentOS 5 でも透過圧縮を利用

CentOS 5 で運用しているサーバで、容量を稼ぐのに透過圧縮可能なファイルシステムを使いたいのですが、ZFS on Linux は非対応(カーネルが古くコンパイル不可)なので、zfs-fuse を利用しようかと思います。しかし、CentOS 5 の fuse は、NFS export に対応していません。
そこで、一工夫して、透過圧縮指定した ZFS 領域にスパースファイルを作って XFS 化して、loop マウントすることで、NFS export することにしました。
※まず圧縮指定
# zfs set compression=gzip-1 tank5/test
# zfs get compression tank5/test
NAME        PROPERTY     VALUE     SOURCE
tank5/test  compression  gzip-1    local

※スパースファイル作成。CentOS 5 では truncate が用意されてないので dd 利用
# dd if=/dev/zero of=/tank5/test/sparsefile bs=1M seek=4096 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 2.2e-05 seconds, 0.0 kB/s

# ls -lsh /tank5/test/sparsefile 
512 -rw-r--r-- 1 root root 4.0G Jun 29 10:21 /tank5/test/sparsefile

※ext4 でもいいけれど、XFS を試したいという気持ちもありまして
# mkfs -t xfs /tank5/test/sparsefile 
meta-data=/tank5/test/sparsefile isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount -t xfs -o loop /tank5/test/sparsefile /mnt_temp
# df
...
/tank5/test/sparsefile
                       4184064      4384   4179680   1% /mnt_temp

※テスト書き込み
# dd if=/dev/sda of=/mnt_temp/test.dd bs=1M count=500 conv=fsync
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 16.7982 seconds, 31.2 MB/s
# ls -lsh /tank5/test/sparsefile 
211M -rw-r--r-- 1 root root 4.0G Jun 29 10:24 /tank5/test/sparsefile
この実験では、500M が 211M に圧縮されました。書き込み速度は、zfs-fuse の遅さに引きずられますが、NFS (NW が 100Mbps の環境) 経由で利用する予定なので、十分そうです。
なお、NFS のセッティング方法等は、普通にやればいいので割愛します。

2013-06-30追記
XFS のサイズ拡張(xfs_growfs)を試してみました。マウントしたまま可能でした。
スパースファイルの拡張、loop デバイスのサイズ拡張、xfs_growfs の順に行います。
※losetup -c も初めてなので、予め loop デバイスのサイズを確認
# grep loop0 /proc/partitions 
   7        0    4194304 loop0

※スパースファイルの拡張、サイズ指定を誤っても変なところに書き込まないように if=/dev/null でね
# dd if=/dev/null of=/tank5/test/sparsefile bs=1M seek=8192 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.646e-05 s, 0.0 kB/s
# ls -lsh /tank5/test/sparsefile 
236M -rw-r--r-- 1 root root 8.0G Jun 30 06:06 /tank5/test/sparsefile

※loop デバイスのサイズ認識は自動ではないので、変化なし
# grep loop0 /proc/partitions 
   7        0    4194304 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※loop デバイスのサイズ再認識を実行
# losetup -c /dev/loop0 
# grep loop0 /proc/partitions 
   7        0    8388608 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※XFS のサイズ拡張を実行
# xfs_growfs /mnt_temp
meta-data=/dev/loop0             isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0, projid32bit=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 1048576 to 2097152
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       8378368    545312   7833056   7% /mnt_temp
実験の範囲では大丈夫そうです。

2013-07-03追記
サイズ拡張の検証を、間違って CentOS 6 でやってしまっていました。通常、CentOS 6 を使うことが多いもので・・・
で、残念ながら、CentOS 5 では losetup -c オプションは使えず、いちおう 2.6.18-348.el5 のソースも見てみましたが、サイズ拡張を行うためのインターフェースが未実装でした。したがって、マウントしたまま拡張は不可でした。もちろん、いったんアンマウントしてから、スパースファイル拡張して、再度マウントすればいけます。

2013-08-09追記
この形態で実際使い始めたのですが、ファイル削除の際に一工夫すると、より効果的に運用できます。具体的には次のように、削除対象ファイルをゼロ埋め後に削除するようにします。
# find remove-target-dir -type f -exec shred -n 0 -z -u {} \;
これで不要となったブロックについて、XFS から ZFS へゼロ書き込みが行われ、ZFS 側の圧縮機能により元データが使用していたブロックの大半が回収されることになります。したがって、シン・プロビジョニング(Thin Provisioning)が、より効果的に行えることになります。
なお、上記の find 後には、抜けがら(通常ファイル以外のディレクトリその他のことを言ってます:-)が残りますので、最後に rm -rf remove-target-dir もお忘れなく。

2013-10-22追記
オラクル社提供の UEK を使うことで、CentOS 5 でも ZFS on Linux や btrfs が利用できました。
こちらの記事を参照。

0 件のコメント:

コメントを投稿

人気ブログランキングへ にほんブログ村 IT技術ブログへ