ZFSの重複排除機能がどの範囲で有効なのか(ボリューム?プール?ディレクトリ?)気になったので調べてみた。
環境
調査
準備
適当にボリュームを作成
# zfs list NAME USED AVAIL REFER MOUNTPOINT vol 104K 1000G 31K /vol # zfs create vol/test # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 141K 1000G 30K /vol vol/test 30K 1000G 30K /vol/test
重複排除を有効化
# zfs set dedup=on vol/test # zfs get all vol/test NAME PROPERTY VALUE SOURCE vol/test type filesystem - vol/test creation Thu Apr 11 21:05 2013 - vol/test used 30K - vol/test available 1000G - vol/test referenced 30K - vol/test compressratio 1.00x - vol/test mounted yes - vol/test quota none default vol/test reservation none default vol/test recordsize 128K default vol/test mountpoint /vol/test default vol/test sharenfs off default vol/test checksum on default vol/test compression off default vol/test atime on default vol/test devices on default vol/test exec on default vol/test setuid on default vol/test readonly off default vol/test zoned off default vol/test snapdir hidden default vol/test aclinherit restricted default vol/test canmount on default vol/test xattr on default vol/test copies 1 default vol/test version 5 - vol/test utf8only off - vol/test normalization none - vol/test casesensitivity sensitive - vol/test vscan off default vol/test nbmand off default vol/test sharesmb off default vol/test refquota none default vol/test refreservation none default vol/test primarycache all default vol/test secondarycache all default vol/test usedbysnapshots 0 - vol/test usedbydataset 30K - vol/test usedbychildren 0 - vol/test usedbyrefreservation 0 - vol/test logbias latency default vol/test dedup on local vol/test mlslabel none default vol/test sync standard default vol/test refcompressratio 1.00x - vol/test written 30K - vol/test snapdev hidden default
重複排除の確認
まずは重複排除が動作するか確認(確実に動くだろうけど一応…)
# dd if=/dev/urandom of=test bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 275.28 s, 3.9 MB/s # ls -lh total 1.1G -rw-r--r-- 1 root root 1.0G Apr 11 21:12 test # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 1.00G 999G 31K /vol vol/test 1.00G 999G 1.00G /vol/test
ファイルをコピーしてみる
# cp test test2 # ls -lh total 2.1G -rw-r--r-- 1 root root 1.0G Apr 11 21:12 test -rw-r--r-- 1 root root 1.0G Apr 11 21:13 test2 # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 2.00G 999G 31K /vol vol/test 2.00G 999G 2.00G /vol/test
ってな感じで、見た目上は1GBのファイルが2つできているがファイルシステム上では、 1GBしか使用していない。
zdbでも確認してみる。
# zdb -S vol Simulated DDT histogram: bucket allocated referenced ______ ______________________________ ______________________________ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 2 8K 1G 1G 1G 16K 2G 2G 2G Total 8K 1G 1G 1G 16K 2G 2G 2G dedup = 2.00, compress = 1.00, copies = 1.00, dedup * compress / copies = 2.00
dedupが2.00になっており、200%(って書き方はおかしいけど)の効果を発揮していることがわかる。
一つ上の階層で試してみる
vol/ 直下にテストファイルをコピーしてみる。 この領域は重複排除がOFFになっているのでこちらは単純増加するはず。
# cp test ../test3 # ls -lh ../ total 1.1G drwxr-xr-x 2 root root 4 Apr 11 21:13 test -rw-r--r-- 1 root root 1.0G Apr 11 21:23 test3 # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 3.01G 998G 1.00G /vol vol/test 2.00G 998G 2.00G /vol/test # zdb -S vol Simulated DDT histogram: bucket allocated referenced ______ ______________________________ ______________________________ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 1 8K 1G 1G 1G 8K 1G 1G 1G 2 8K 1G 1G 1G 16K 2G 2G 2G Total 16K 2G 2G 2G 24K 3G 3G 3G dedup = 1.50, compress = 1.00, copies = 1.00, dedup * compress / copies = 1.50
予想通りの結果
ディレクトリ配下にコピーしてみる
vol/testボリューム配下にディレクトリを作成し、その下にコピーしてみる。
# mkdir dir1 # cp test dir1/test4 # ls -lh dir1/ total 1.1G -rw-r--r-- 1 root root 1.0G Apr 11 21:26 test4 # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 4.01G 998G 1.00G /vol vol/test 3.00G 998G 3.00G /vol/test # zdb -S vol Simulated DDT histogram: bucket allocated referenced ______ ______________________________ ______________________________ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 1 8K 1G 1G 1G 8K 1G 1G 1G 2 8K 1G 1G 1G 24K 3G 3G 3G Total 16K 2G 2G 2G 32K 4G 4G 4G dedup = 2.00, compress = 1.00, copies = 1.00, dedup * compress / copies = 2.00
この場合でも、重複排除が働くことがわかる。
別のボリュームにコピーしてみる
新しいボリュームを作成し、そちらへコピーしてみる。 この時、新しいボリュームでも重複排除機能を有効化する。
# zfs create vol/test2 # zfs set dedup=on vol/test2 # ls -lhd ../test2 drwxr-xr-x 2 root root 2 Apr 11 21:28 ../test2 # cp test ../test2/test5 # zfs list NAME USED AVAIL REFER MOUNTPOINT vol 5.01G 998G 1.00G /vol vol/test 3.00G 998G 3.00G /vol/test vol/test2 1.00G 998G 1.00G /vol/test2 # zdb -S vol Simulated DDT histogram: bucket allocated referenced ______ ______________________________ ______________________________ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 1 8K 1G 1G 1G 8K 1G 1G 1G 4 8K 1G 1G 1G 32K 4G 4G 4G Total 16K 2G 2G 2G 40K 5G 5G 5G dedup = 2.50, compress = 1.00, copies = 1.00, dedup * compress / copies = 2.50
別のボリュームでも重複排除が働いた! これは予想外。
重複排除のメタデータはプール毎に持っているので、別々のボリュームになっても機能するということかな?