今回は ZFS の大きな特徴の一つである,圧縮にフォーカスしたいと思います.
ZFS はファイルシステム (ZVOLも) の圧縮が利用でき,透過的に圧縮・展開が行われます.
これによってストレージ利用量の削減が見込めます.
- ZFS に関するお話
- FreeBSD で ZFS を利用する – ZFS 概要
- FreeBSD で ZFS を利用する – ZFS プールの作成 (パーティション切らない編)
- FreeBSD で ZFS を利用する – ZFS プールの機能について理解する
- FreeBSD で ZFS を利用する – ファイルシステムを管理する
- FreeBSD で ZFS を利用する – send/recv を使い倒す
- FreeBSD で ZFS を利用する – RAWボリュームを切り出す & iSCSI として提供する
- FreeBSD で ZFS を利用する – ファイルシステムの圧縮を利用する・比較する
- FreeBSD で ZFS を利用する – ZFS のキャッシュの仕組みを理解する
- FreeBSD で ZFS を利用する – キャッシュを構成・設定する
- FreeBSD で ZFS を利用する – 重複排除を利用する・確認する
- FreeBSD で ZFS を利用する – ZFS ファイルシステムの機能について理解する (1)
- FreeBSD で ZFS を利用する – ZFS ファイルシステムの機能について理解する (2)
- FreeBSD で ZFS を利用する – ZFS ファイルシステムの機能について理解する (3)
- FreeBSD で ZFS を利用する – ZFS ファイルシステムの機能について理解する (4)
ファイルシステムの圧縮
ZFS でのファイルシステムの圧縮にはいくつかのアルゴリズムがあります.
それぞれ得手・不得手がありますので格納するデータに応じた圧縮方式を適用することが推奨されます.
- LZ4
圧縮・展開の速さ,CPU 負荷の少なさに定評があり,現在 compression=on の場合のデフォルト値となっている.ZSTD よりも高速と言われている. - GZIP
圧縮率は高いが CPU 負荷も高い.バックアップ領域など静的なデータを長期保存し普段読み書きアクセスを頻繁に行わない所には良いと思う. - LZJB
LZ4 と GZIP の中間位の立ち位置で,圧縮率に優れている.展開は LZ4 の方が速い. - ZLE
連続するゼロデータ (0 が連続するデータ) の所のみ圧縮を行う.負荷は低いが効果も低い. - ZSTD
たぶん今後のスタンダードになるもの.圧縮・展開の速さは LZ4 と同等,圧縮率が GZIP に近しい.CPU 負荷は LZ4 より少し高い.というもの
と,色々ありますので,それぞれどのような効果・パフォーマンスなのかを測定してみます.
それぞれのアルゴリズムでの圧縮・展開の測定
測定の方法ですが,各ファイルシステムにFreeBSD のソースファイル「src_stable_13.tar.xz」を展開して展開にかかる時間,圧縮率の測定.
また,逆に展開されたソースファイル群を tar で読み出して /dev/null に書き出してかかる時間を測定してみます.
時間に関しては仮想環境上ですのでブレが生じる事を前提に見て頂ければと思います.
CPU 負荷についてはこれも仮想上なのでより参考にできないと思いますので取得しません.
LZ4
まず,LZ4 で圧縮するファイルシステムの作成を行います.
# zfs create pool0/lz4 # zfs set compression=lz4 pool0/lz4 # zfs get compression pool0/lz4 NAME PROPERTY VALUE SOURCE pool0/lz4 compression lz4 local # mkdir /pool0/lz4/src1 # mkdir /pool0/lz4/src2 # mkdir /pool0/lz4/src3
3回実施して計測しますので,/pool0/lz4/src[1-3] ができると理解ください.
書き込み: 1回目
# cd /pool0/lz4/src1 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:25:38 JST 2023 Sat Dec 23 13:26:01 JST 2023 # zfs get compressratio pool0/lz4 NAME PROPERTY VALUE SOURCE pool0/lz4 compressratio 2.42x -
書き込み: 2回目
# cd /pool0/lz4/src2 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:27:29 JST 2023 Sat Dec 23 13:27:50 JST 2023 # zfs get compressratio pool0/lz4 NAME PROPERTY VALUE SOURCE pool0/lz4 compressratio 2.42x -
書き込み: 3回目
# cd /pool0/lz4/src3 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:28:55 JST 2023 Sat Dec 23 13:29:17 JST 2023 # zfs get compressratio pool0/lz4 NAME PROPERTY VALUE SOURCE pool0/lz4 compressratio 2.42x -
書き込み: まとめ
1回目 23秒,2回目 21秒,3回目 22秒.平均22秒かかりました.
圧縮率は 2.42 ということで元データと比較して 140% の圧縮率でした.
なお,1.00 が無圧縮となります
ちなみに,展開したデータの実容量としては次のとおり 613MB です.
# du -sk /pool0/lz4/src1 628350 /pool0/lz4/src1
読み出し: 1回目
# cd /pool0/lz4/src1 # date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:34:21 JST 2023 Sat Dec 23 13:34:26 JST 2023
読み出し: 2回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:35:09 JST 2023 Sat Dec 23 13:35:13 JST 2023
読み出し: 3回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:35:58 JST 2023 Sat Dec 23 13:36:01 JST 2023
読み出し: まとめ
1回目が5秒,2回目が4秒,3回目が3秒でした.ですので平均4秒で 630MB の読み出しができている事になります.
なお,2回目以降はキャッシュに入ったので速度が上がる可能性が高いです.
GZIP
まず,GZIP で圧縮するファイルシステムの作成を行います.
# zfs create pool0/gzip # zfs set compression=gzip pool0/gzip # zfs get compression pool0/gzip NAME PROPERTY VALUE SOURCE pool0/gzip compression gzip local # mkdir /pool0/gzip/src1 # mkdir /pool0/gzip/src2 # mkdir /pool0/gzip/src3
3回実施して計測しますので,/pool0/gzip/src[1-3] ができると理解ください.
書き込み: 1回目
# cd /pool0/gzip/src1 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:41:44 JST 2023 Sat Dec 23 13:42:23 JST 2023 # zfs get compressratio pool0/gzip NAME PROPERTY VALUE SOURCE pool0/gzip compressratio 3.60x -
書き込み: 2回目
# cd /pool0/gzip/src2 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:43:17 JST 2023 Sat Dec 23 13:43:57 JST 2023 # zfs get compressratio pool0/gzip NAME PROPERTY VALUE SOURCE pool0/gzip compressratio 3.59x -
書き込み: 3回目
# cd /pool0/gzip/src3 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:44:46 JST 2023 Sat Dec 23 13:45:25 JST 2023 # zfs get compressratio pool0/gzip NAME PROPERTY VALUE SOURCE pool0/gzip compressratio 3.59x -
書き込み: まとめ
1回目 39秒,2回目 40秒,3回目 39秒.平均39秒かかりました.
圧縮率は 3.59 ということで元データと比較して 260% の圧縮率でした.
LZ4 と比べて時間 (CPU 負荷) は高いものの,圧縮率はとても良いことが分かります.
読み出し: 1回目
# cd /pool0/gzip/src1 # date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:49:34 JST 2023 Sat Dec 23 13:49:56 JST 2023
読み出し: 2回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:50:01 JST 2023 Sat Dec 23 13:50:09 JST 2023
読み出し: 3回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 13:50:49 JST 2023 Sat Dec 23 13:50:57 JST 2023
読み出し: まとめ
1回目が22秒,2回目が8秒,3回目が8秒でした.ですので平均13秒で 630MB の読み出しができている事になります.
なお,2回目以降はキャッシュに入ったので速度が上がる可能性が高いです.
LZ4 と1回目の比較をすると17秒の違いがありますので,圧縮データの展開時も CPU 負荷は高めだと思います.
LZJB
まず,LZJB で圧縮するファイルシステムの作成を行います.
# zfs create pool0/lzjb # zfs set compression=lzjb pool0/lzjb # zfs get compression pool0/lzjb NAME PROPERTY VALUE SOURCE pool0/lzjb compression lzjb local # mkdir /pool0/lzjb/src1 # mkdir /pool0/lzjb/src2 # mkdir /pool0/lzjb/src3
3回実施して計測しますので,/pool0/lzjb/src[1-3] ができると理解ください.
書き込み: 1回目
# cd /pool0/gzip/src1 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:58:24 JST 2023 Sat Dec 23 13:58:51 JST 2023 # zfs get compressratio pool0/lzjb NAME PROPERTY VALUE SOURCE pool0/lzjb compressratio 2.12x -
書き込み: 2回目
# cd /pool0/lzjb/src2 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 13:59:36 JST 2023 Sat Dec 23 13:59:58 JST 2023 # zfs get compressratio pool0/lzjb NAME PROPERTY VALUE SOURCE pool0/lzjb compressratio 2.12x -
書き込み: 3回目
# cd /pool0/lzjb/src3 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:00:43 JST 2023 Sat Dec 23 14:01:05 JST 2023 # zfs get compressratio pool0/lzjb NAME PROPERTY VALUE SOURCE pool0/lzjb compressratio 2.12x -
書き込み: まとめ
1回目 27秒,2回目 22秒,3回目 22秒.平均24秒かかりました.
圧縮率は 2.12 ということで元データと比較して 210% の圧縮率でした.
LZ4 と比べて時間 (CPU 負荷) は高いものの,GZIP 程ではなく,圧縮率も GZIP 程ではないものの良い結果となっています.
読み出し: 1回目
# cd /pool0/lzjb/src1 # date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:05:17 JST 2023 Sat Dec 23 14:05:59 JST 2023
読み出し: 2回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:06:34 JST 2023 Sat Dec 23 14:06:40 JST 2023
読み出し: 3回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:07:05 JST 2023 Sat Dec 23 14:07:12 JST 2023
読み出し: まとめ
1回目が42秒,2回目が6秒,3回目が7秒でした.初回が GZIP より時間がかかっているのは予定外です.本来は少なくなるはず… 平均18秒で 630MB の読み出しができている事になります.
2回目,3回目の値が GZIP に比べて低いため,やり直せば1回目も値が違ってきているとは思います.
いずれにぜよ,速度・圧縮率の観点で LZ4 と GZIP の間に位置する事はわかるかと思います.
ZLE
まず,ZLE で圧縮するファイルシステムの作成を行います.
# zfs create pool0/zle # zfs set compression=zle pool0/zle # zfs get compression pool0/zle NAME PROPERTY VALUE SOURCE pool0/zle compression zle local # mkdir /pool0/zle/src1 # mkdir /pool0/zle/src2 # mkdir /pool0/zle/src3
3回実施して計測しますので,/pool0/zle/src[1-3] ができると理解ください.
書き込み: 1回目
# cd /pool0/zle/src1 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:22:48 JST 2023 Sat Dec 23 14:23:13 JST 2023 # zfs get compressratio pool0/zle NAME PROPERTY VALUE SOURCE pool0/zle compressratio 1.07x -
書き込み: 2回目
# cd /pool0/zle/src2 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:24:41 JST 2023 Sat Dec 23 14:25:06 JST 2023 # zfs get compressratio pool0/zle NAME PROPERTY VALUE SOURCE pool0/zle compressratio 1.07x -
書き込み: 3回目
# cd /pool0/zle/src3 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:25:46 JST 2023 Sat Dec 23 14:26:10 JST 2023 # zfs get compressratio pool0/zle NAME PROPERTY VALUE SOURCE pool0/zle compressratio 1.07x -
書き込み: まとめ
1回目 25秒,2回目 25秒,3回目 24秒.平均25秒かかりました.
圧縮率は 1.07 ということで元データと比較して 10% 未満の圧縮率でした.
初めて試してみましたが,これは自分が採用する事はないな.と思いました.
通常のファイルサーバーとしての利用の場合,これを採用するメリットはないと思います.データベース製品で最初にファイルシステムにゼロ埋めを行うものがありますが,こういったものには有効なのだと思いますが…
読み出し: 1回目
# cd /pool0/zle/src1 # date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:30:22 JST 2023 Sat Dec 23 14:31:08 JST 2023
読み出し: 2回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:31:35 JST 2023 Sat Dec 23 14:32:05 JST 2023
読み出し: 3回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:32:30 JST 2023 Sat Dec 23 14:32:53 JST 2023
読み出し: まとめ
1回目が46秒,2回目が30秒,3回目が23秒でした.圧縮されているデータがそもそも少ないため,読み出しにかかる量が多くなりその結果時間がかかっているという状況だと思います.
ZSTD
まず,ZSTD で圧縮するファイルシステムの作成を行います.
# zfs create pool0/zstd root@bsd13-1:/pool0/zle/src1 # zfs set compression=zstd pool0/zstd root@bsd13-1:/pool0/zle/src1 # zfs get compression pool0/zstd NAME PROPERTY VALUE SOURCE pool0/zstd compression zstd local # mkdir /pool0/zstd/src1 # mkdir /pool0/zstd/src2 # mkdir /pool0/zstd/src3
3回実施して計測しますので,/pool0/zstd/src[1-3] ができると理解ください.
書き込み: 1回目
# cd /pool0/zstd/src1 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:38:29 JST 2023 Sat Dec 23 14:38:52 JST 2023 # zfs get compressratio pool0/zstd NAME PROPERTY VALUE SOURCE pool0/zstd compressratio 3.47x -
書き込み: 2回目
# cd /pool0/zstd/src2 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:39:45 JST 2023 Sat Dec 23 14:40:07 JST 2023 # zfs get compressratio pool0/zstd NAME PROPERTY VALUE SOURCE pool0/zstd compressratio 3.47x -
書き込み: 3回目
# cd /pool0/zstd/src3 # date ; tar -Jxf /root/src_stable_13.tar.xz ; date Sat Dec 23 14:40:58 JST 2023 Sat Dec 23 14:41:21 JST 2023 # zfs get compressratio pool0/zstd NAME PROPERTY VALUE SOURCE pool0/zstd compressratio 3.47x -
書き込み: まとめ
1回目 23秒,2回目 22秒,3回目 23秒.平均23秒かかりました.
圧縮率は 3.47 ということで元データと比較して 240% の圧縮率でした.
GZIP よりは多少劣りますがかかる時間は LZ4 並みの時間でした.
読み出し: 1回目
# cd /pool0/zstd/src1 # date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:45:21 JST 2023 Sat Dec 23 14:45:36 JST 2023
読み出し: 2回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:46:13 JST 2023 Sat Dec 23 14:46:26 JST 2023
読み出し: 3回目
# date ; tar -cf /dev/null ./ ; date Sat Dec 23 14:46:47 JST 2023 Sat Dec 23 14:47:15 JST 2023
読み出し: まとめ
1回目が15秒,2回目が13秒,3回目が28秒でした.3回目が遅いのは環境の問題が高いと思います.
平均としては19秒で,GZIP よりは速く,LZ4 や LZJB より遅いという結果です.
まとめ
これらを纏めると次のとおりとなります.
書き込み時 (圧縮時)
アルゴリズム | 1回目 | 2回目 | 3回目 | 平均 | 圧縮率 |
LZ4 | 23秒 | 21秒 | 22秒 | 22秒 | 2.42 |
GZIP | 39秒 | 40秒 | 39秒 | 39秒 | 3.59 |
LZJB | 27秒 | 22秒 | 22秒 | 24秒 | 2.12 |
ZLE | 25秒 | 25秒 | 25秒 | 24秒 | 1.07 |
ZSTD | 23秒 | 22秒 | 23秒 | 23秒 | 3.47 |
書き込み時の速度で並べると LZ4 -> ZSTD -> LZJB | ZLE -> GZIP の順番
圧縮率で並べると GZIP -> ZSTD -> LZ4 -> LZJB -> ZLE の順番でした.
読み出し時 (展開時)
アルゴリズム | 1回目 | 2回目 | 3回目 | 平均 |
LZ4 | 5秒 | 4秒 | 3秒 | 4秒 |
GZIP | 22秒 | 8秒 | 8秒 | 13秒 |
LZJB | 42秒 | 6秒 | 7秒 | 18秒 |
ZLE | 46秒 | 30秒 | 23秒 | 33秒 |
ZSTD | 15秒 | 13秒 | 28秒 | 19秒 |
読み出し時の速度で見ると LZ4 -> GZIP -> ZSTD -> LZJB -> ZLE の順番でした.
仮想環境上での比較ですのでちょっとしたことでブレが発生しますが,それぞれの圧縮アルゴリズムの特徴が理解できたのではないでしょうか.
ファイルサーバーとして読み書き速度を最重要視したい場合は LZ4 になると思います.圧縮率も重視したい場合は ZSTD を選択.という形に.また,アーカイブやバックアップ目的は GZIP を採用というのが特性に合っているかと思います.
実際の所は自身のファイルサーバーの目的・役割に応じて選択いただくことになりますが,概ねの傾向として参考にして頂ければと思います.
コメント