ZFSerの皆様におかれましては、OpenZFS 2.0で圧縮アルゴリズムにZStandardが追加されたのは周知の事実だろう。compressionの値としてzstd-N
とzstd-fast-N
が指定できるようになったが、設定値と圧縮率の関係性は以下のとおり。
(速度重視)← | 設定値 | →(圧縮重視) |
zstd-fast-1000 ~ zstd-fast-1 / zstd-1 ~ zstd-19 |
zstd
とzstd-fast
で数値の関係性が逆転しているように見えるが(というか設定値上はそういう風にしか見えないのだが)、zstd-fast
の方は負数を表しており、-1000が最小でスーパー速度重視ということなので一貫性が取れている。
ZStandardはLZ4より圧縮率が高く、それに応じて処理負荷も若干高いとされている。実際のところどんなものか、簡易的にテストした。
個人的にアーカイブ用途に使いたいので、圧縮率重視ってことでzstd
のみが対象。だいぶてきとーな実験なので、あくまで傾向を掴むもの程度で見て欲しい。
ZFSの主要開発者の1人、Allan Judeによる真っ当なベンチマークも参照されたし。
テスト環境は以下のとおり。
テストデータをコピー元のRAID-Z2プールから、テスト用のコピー先プールにrsyncでコピーする。cpじゃなくてrsyncなのは、終了時に転送速度を表示してくれて便利だからってだけで、他意はない。
圧縮アルゴリズム別のファイルシステムを作ってはコピーしての繰り返しで、途中プールの作り直しやファイルシステム削除はしてないので、HDDの外周/内周の転送速度差がテストに影響していることに注意。
加えて、仮想マシン上での実行だったり、テスト中もファイルサーバとして普通にアクセスしたり(といっても負荷をかけないよう自粛はしたけど)と、結果には様々なノイズが混入している点にも注意。
各圧縮方法ごとの圧縮後容量、圧縮率(無圧縮時を100%とした時の割合)、転送速度を下表にまとめる。
パターン | 圧縮方法 | 容量(GiB) | 圧縮率(%) | 速度(MiB/s) | 備考 |
---|---|---|---|---|---|
1 | lz4 | 483.6 | 96.3 | 115.8 | |
2 | zstd-3 | 477.3 | 95.0 | 115.0 | 数値なしのzstd を指定した場合に使われる値 |
3 | zstd-7 | 476.5 | 94.8 | 111.0 | |
ここで2~3を削除 | |||||
4 | zstd-15 | 476.3 | 94.8 | 100.4 | |
5 | zstd-19 | 475.3 | 94.6 | 24.5 | |
6 | gzip-9 | 478.8 | 95.3 | 71.6 | |
7 | zstd-3 | 477.3 | 95.0 | 112.0 | HDDの外周/内周の影響確認用 |
8 | lz4 | 483.6 | 96.3 | 109.4 | 〃 |
9 | off | 502.4 | 100.0 | 108.9 | 無圧縮。基準値 |
パターン1~3実行後、一応、HDDの内外周差を気にしてパターン1,2のデータは削除している。
パターン9が基準値。無圧縮で最内周に書き込んでいるので、これより遅いかどうかで、圧縮処理がボトルネックになっているかの目安になるかなと。書き込み先がHDD 1台のプールなので、そこで律速されてる感があるけど、まぁ実際の使われ方に近い環境ってことで大目に見てください。
グラフで表したのが下図。
まず言えることはzstd-3
のバランスの良さ。LZ4と遜色ない速度にもかかわらず、圧縮率は有意に高い。さすが、compress=zstd
とした時に使われるレベルだけある。gzip-9
より縮むのに大分速いってのは特筆すべき。
圧縮率最重視のzstd-19
が当然ながら最も縮むが、速度が大分厳しい感じ。少なくとも今回のテストデータでは、処理時間に見合うだけの効果が得られているとは言い難い。仮に最新CPUで速度が10倍になったとしても、250MB/s程度でボトルネックとなる可能性が高く使いどころが難しそう。費用対効果が高いのはzstd-7
、状況によってはzstd-15
もなくはないかな。
ついでに、圧縮はrecordsize
が大きいほど効果的とされているので、その影響も軽く測定。
LZ4とZStandardのそれぞれで、レコードサイズを512kから1Mに変更した時の圧縮後容量の差分を求めたのが下表。
圧縮方法 | recsize | 圧縮後容量(MiB) | 128kとの差分(MiB) | 無圧縮容量に占める削減割合 |
---|---|---|---|---|
lz4 | 128k | 495251.3 | - | - |
512k | 495145.0 | -106.3 | -0.02% | |
1M | 495251.4 | +0.1 | +0.00% | |
zstd-7 | 128k | 490354.9 | - | - |
512k | 488842.4 | -1512.5 | -0.29% | |
1M | 487907.2 | -2447.7 | -0.48% |
なぜかLZ4のレコードサイズ1MBの時は圧縮率が下がってるけど、概ねレコードサイズが大きくなるほど圧縮率も向上するようだ。割合で見ると微々たるものだが、レコードサイズを変えるだけで恩恵が得られるのはありがたい。実のところ、レコードサイズを大きくすると実データに占めるメタデータ割合(ハッシュの量)が減り、プール容量的にはこちらの影響の方が大きかったりする(参考:ZFSのSpecial vdevを試してみる)
とりあえず、互換性を気にしなくていい環境では、lz4の代わりに積極的にzstdを使っていくのが良さそう。可能な限りrecordsizeも大きくしていこう(ただし、FreeBSDはレコードサイズが128k超のファイルシステムからブート出来ない点には注意が必要。)