FreeBSDのZFSは既にプロダクションレベルに達しており、我が家のサーバも3年以上の運用期間でノートラブルという実績があります。壊れたら修復は絶望的ですが、別デバイスにバックアップさえ取っておけばスナップショットで差分バックアップの代わりになるしデバイスを追加して容量拡張とか簡単だしそもそもファイルシステムとしては頑丈っぽいし良い事ずくめです。
そんなZFSに DEDUP というこれまたスゴい機能があるのだそうです。DEDUPというのは deduplicationだそうで、「データが重複してるとディスクがもったいないから無くしましょう」という考え。重複するから節約というのはハードリンクとかシンボリックリンクでもよく似ていますが、ZFSのそれはブロックごとに比較して重複していれば共通化するという力技。ハードリンクと違って共通化しても片方を編集した時に他方は影響を受けません(そのかわり共通でなくなるので容量は増える)。
てことで、はたしてそんなうまく機能するのか手元の環境で実験してみました。
はじめの状態toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 31K 570G 31K /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 346G 585G 37% 1.00x ONLINE -
作成したてのファイルシステムなのでサイズが非常に小さいです。この時点でのプール全体の使用量は346GB。
大きいファイルを gettoriyu# smbclient //whs2011/ドキュメント -c "get ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso"
Enter root's password:
Domain=[WHS2011] OS=[Windows Home Server 2011 7601 Service Pack 1] Server=[Windows Home Server 2011 6.1]
getting file ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso of size 4409899008 as ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso (28295.8 KiloBytes/sec) (average 28295.8 KiloBytes/sec)
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 4.11G 565G 4.11G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 350G 581G 37% 1.00x ONLINE -
smbclient経由で4GBのファイルをgetしたところ、使用量が4GBほど増えました。計算が合います。
単純コピーtoriyu# cp ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso test1.iso
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 8.22G 561G 8.22G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 355G 576G 38% 1.00x ONLINE -
DEDUPは使っていないファイルシステムなので、普通にコピーすると当然使用量が増えます。
DEDUPを有効にしてみるtoriyu# zfs set dedup=on tank/test試しにコピーしてみる
toriyu# zfs get dedup tank/test
NAME PROPERTY VALUE SOURCE
tank/test dedup on local
toriyu# cp ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso test2.iso
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 12.3G 557G 12.3G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 359G 572G 38% 1.00x ONLINE -
ん? 普通に増えてますね。DEDUPの効果は無いのでしょうか?
もう一度コピーしてみるtoriyu# cp ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso test3.iso
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 16.4G 557G 16.4G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 359G 572G 38% 2.00x ONLINE -
お、今度は zfs list では増えてるにも関わらず、zpool list では使用量が変わってませんね。DEDUPも2.00xになっています。どうやら共通化する元のブロックもdedup=onにした後で書き込まれないと効果がないようです。
cpではなく再度smbclientでgetしてみるtoriyu# smbclient //whs2011/ドキュメント -c "get ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso test4.iso"
Enter root's password:
Domain=[WHS2011] OS=[Windows Home Server 2011 7601 Service Pack 1] Server=[Windows Home Server 2011 6.1]
getting file ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso of size 4409899008 as test4.iso (23046.8 KiloBytes/sec) (average 23046.8 KiloBytes/sec)
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 20.6G 557G 20.6G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 359G 572G 38% 3.00x ONLINE -
cpと違って、今度はカーネルにすれば重複領域があることを予め知る術が無いはずですが、これまたちゃんと共通化してディスク使用量はさっきと変わりありません。なかなか優秀です。
snapshotを作ってファイルを削除toriyu# zfs snapshot tank/test@snapshot1
toriyu# ls
ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso
test1.iso
test2.iso
test3.iso
test4.iso
toriyu# rm *.iso
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 20.6G 557G 39K /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 359G 572G 38% 3.00x ONLINE -
ZFSを使っている方にはよくお分かりかと思いますが、snapshotを作成してファイルを削除しても容量は減りません。
再び smbclient で gettoriyu# smbclient //whs2011/ドキュメント -c "get ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso test5.iso"
Enter root's password:
Domain=[WHS2011] OS=[Windows Home Server 2011 7601 Service Pack 1] Server=[Windows Home Server 2011 6.1]
getting file ja_server_install_disc_windows_home_server_2011_x64_dvd_660489.iso of size 4409899008 as test5.iso (25552.0 KiloBytes/sec) (average 25552.0 KiloBytes/sec)
toriyu# zfs list tank/test
NAME USED AVAIL REFER MOUNTPOINT
tank/test 24.7G 557G 4.11G /tank/test
toriyu# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
tank 931G 359G 572G 38% 4.00x ONLINE -
嬉しいことに、削除済みでsnapshotの中にのみ存在する領域でも有効のようです。
ということで、実験した結果のまとめ。
dedupプロパティはファイルシステム毎に設定できますから、内容が重複することがわかっており容量削減が重要な用途の場合は便利に使えるのでしょう。(どんな用途か思いつきませんけど ^^)
06/13 | ( 通りすがり ) |
pdumpfsを使うような用途で生きてくるかも知れませんね。 ハードリンクでは共有できなパーミッションが音なるケースでもメタデータとは独立なのでdedupなら有効ですし。 | |
06/13 | ( たかたに ) |
なるほど、pdumpfsですか。と言いつつググる(笑) うちではzfsのスナップショットを世代バックアップの代わりに使ってますが、確かにpdumpfsで単一ファイルを更新していく時(メールボックスとか)に効果ありそうですね。勉強になります。 | |
06/14 | ( 通りすがり ) |
「pdumpfsを使うような用途」という言い回しは判りにくかったです。 pdumpfs(やrsyncの--link-dest)はハードリンクで重複冗長を避けています(ですからdedupとは機能がダブります)。 ハードリンクは、リンク個数に上限がある、メタデータ(owner permisshin ctime mtime atime 諸々)の1つでも違っても共有できない、fsを跨いでリンクできない、また1バイトでも異なると共有できない等の制約がありますがdedupはこれらがありません。 使い所に悩みますが、jailでユーザランドの複製を多量に必要なケースで劇的にディスク消費を抑えられそうですね。 |