そこで、一工夫して、透過圧縮指定した 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 が利用できました。
こちらの記事を参照。