ほとんどのデータは、アプリケーションの相互運用性を容易にするために、読みやすいファイル形式で保存されます。画像、ビデオ、音声の圧縮には広く使用されている形式がありますが、その他のほとんどのデータは、JSON、CSV、またはその他の同様のテキストベースの形式としてテキストとして保存されます。
Parquet、Avro、ORC などの形式にはオプションの圧縮機能があるため、通常、これらの形式は保存時にすでに圧縮されています。ビデオと画像も通常、汎用形式よりも優れた圧縮率を提供するドメイン固有のアルゴリズムで圧縮されます。
ただし、カスタム データの場合は、アクセスするための解凍手順が含まれない単純な形式でデータを保存することが望ましいです。このデータをディスクに保存する前に圧縮するオプションを提供したいと考えています。
MinIO の圧縮は、システム全体のパフォーマンスに影響を与えることなく透過的な圧縮を可能にするために開発されました。
MinIO は、S2 と呼ばれるSnappyに基づく圧縮方式を使用します。 Snappy コンテンツと互換性がありますが、 2 つの形式拡張子があります。まず第一に、Snappy ストリームに許可されている 64 KB ブロックよりも大きなブロックが許可されます。これにより圧縮が大幅に向上します。次に、「リピート オフセット」を追加します。これにより、主にログ ファイル、JSON、CSV などの機械生成データの圧縮が向上します。また、64 バイトを超える一致を効果的にエンコードできるようになりますが、これは Snappy にとっての問題点です。
S2 では、入力が単一のコアが吸収できる速度よりも速い場合に、複数のブロックを同時に圧縮することもできます。これは、個々のリクエストへの応答性を維持するために重要です。事実上、16 コア以上の制限はメモリ速度になります。
アプライアンス ベンダーによっては、TB あたりのコストを計算する際に、特定の圧縮率を約束したり、想定したりすることがあります。圧縮の場合、1:1 を超える比率は保証されません。データの種類が異なれば、圧縮率も異なります。私たちの意見では、平均圧縮率を提供する意味のある方法はありません。圧縮率は決して単独で評価すべきではありません。実際の圧縮はこれら 2 つの要素のトレードオフであるため、圧縮率は常に圧縮速度と組み合わせる必要があります。
単一のデータ型を比較して違いを観察してみましょう。最大 16 コアを使用して、AMD64 プラットフォーム上でこれらのアルゴリズムの Go 実装を比較します。
まず、横軸は切り捨てられた圧縮率であり、非圧縮サイズからの縮小です。右の方が良いです。参考として、シングルスレッドの gzip レベル 5 が含まれています。
コンプレッサー | 速度 MB/秒 | サイズ | 削減 | 12 MB/秒 |
---|---|---|---|---|
S2デフォルト | 15148 | 1043196283 | 83.37% | 2378 |
S2 ベター | 11551 | 954430842 | 84.79% | 2300 |
S2ベスト | 680 | 832855431 | 86.73% | 2572 |
LZ4最速 | 5645 | 1280414160 | 79.59% | 2680 |
LZ4ベスト | 1552年 | 1091826460 | 82.60% | 2694 |
キビキビ | 946 | 1525176492 | 75.69% | 1828年 |
Gzip L5 | 206 | 942726276 | 84.97% | 557 |
S2 では同時解凍が可能ですが、解凍速度は単一コアを使用します。
このデータでは、Snappy は Gzip リファレンスよりも約 10% 不足しています。削減パーセンテージを扱っているため、これは、Snappy が Gzip 圧縮データの約 1.6 倍のスペースを占有することも意味します。これは、Snappy が Gzip よりも約 4 倍高速に解凍するという事実を無視しています。
通常、LZ4 は Snappy よりも優れていると見なされています。複数のコアでの圧縮を可能にする LZ4 の実装により、この点も明確になります。ただし、基本圧縮の方が優れています。 LZ4 Best (LZ4-HC とも呼ばれる) は、gzip に近い圧縮を提供しますが、解凍は高速ですが、圧縮はインタラクティブな速度ではありません。
S2 は 3 つの圧縮レベルを提供します。 S2 Default は可能な限り高速であり、単一コアの使用に関して Snappy の直接の競合相手と見なすことができます。このデータ タイプでは、どの LZ4 レベルよりもパフォーマンスが向上し、スループットが大幅に向上します。このモードは、アセンブリ実装が利用できないプラットフォームの MinIO によって使用されます。
S2 Better では、CPU を少し消費してより高い圧縮率を得ることができます。ここでの圧縮は Gzip に匹敵しますが、解凍速度は Gzip の方がはるかに優れています。このモードは、アセンブリが利用可能なプラットフォーム (現在は AMD64) 上の MinIO によって使用されます。
S2 Best は、S2 が現在のフォーマットで実行できる最高の圧縮です。これは、圧縮速度やリソースが最も重要ではないが、それでも高速な解凍が必要な状況で使用できます。現在、MinIO はこのモードを使用していませんが、しばらく変更されていないオブジェクトのライフサイクル オプションとして実装される可能性があります。
比較するために、他のデータ型をいくつか比較します。
最新の圧縮の重要な特徴は、事前に圧縮されたデータでも適切に動作することです。従来、事前圧縮されたデータは圧縮アルゴリズムにとって問題でした。多くの場合、圧縮不可能なデータに直面すると、コンプレッサーの速度が不当に遅くなります。
したがって、多くの人は、すでに圧縮されたデータを再圧縮するのは良くないことを本能的に知っています。ただし、最新の実装の多くは、非圧縮セクションを適切な程度まで迅速にスキップできるようになりました。
上記のコンプレッサーの場合、2GiB (2,147,483,647 バイト) の非圧縮データの速度は次のとおりです。
コンプレッサー | 速度 MB/秒 | サイズ | 削減 |
---|---|---|---|
S2デフォルト | 13045 | 2147487753 | 0.00% |
S2 ベター | 9894 | 2147487753 | 0.00% |
S2ベスト | 3938 | 2147487753 | 0.00% |
LZ4高速 | 6400 | 2147485710 | 0.00% |
LZ4ベスト | 12488 | 2147745841 | -0.01% |
キビキビ | 6564 | 2147745801 | -0.01% |
Gzip (ゴー) L5 | 63 | 2148139030 | -0.03% |
Gzip (alt) L5 | 5535 | 2147647512 | -0.01% |
ここでは、この「悪い」動作の代表として、Go 標準ライブラリの gzip も組み込みました。代替の gzip 実装では、この問題は発生しません。それ以外の場合はすべて、コンテンツは非常に高速に処理され、パスが得られます。
これは、MinIO が事前圧縮されたデータを適切に処理できることが期待できることを意味します。
圧縮の一般的な欠点は、ファイル内でスキップする機能が失われることです。この解決策は、ブロックを個別に圧縮し、いくつかの非圧縮オフセットを圧縮解除を開始できる圧縮オフセットにマップするインデックスを保持することです。
独立したブロックを圧縮すると圧縮はわずかに低下しますが、ブロックが大きくなると圧縮も低下します。 Snappy/S2 は、設計によりストリームを独立したブロックとして圧縮します。
MinIO の場合、S3 GetObject リクエストには取得するオプションの範囲を含めることができるため、これは関連します。これにより、オブジェクトの一部を取得できるようになり、それをできるだけ効率的にしたいと考えています。
RELEASE.2022-07-13T23-29-44Z以降、アップロードされる 8MB を超えるすべてのファイル部分に対してインデックスが生成されるようになりました。その後、インデックスが内部的にメタデータに付加されます。これにより、効果的に前方にスキップし、要求されたデータを返すために必要なオブジェクトの部分のみをデコードすることができます。
通常、インデックスは 16 バイト + データ 1 MB あたり約 3 バイトです。これにより、MinIO は、最初のバイトを取得するのと同じ速度で、圧縮ファイル内の任意のバイトを処理できるようになります。
デフォルトでは、MinIO がデータを圧縮してディスク上で暗号化するために追加のパラメータが必要です。これは、この影響を確実に認識していただくためです。
データを圧縮すると、2 つの数値が得られます。非圧縮サイズと圧縮サイズ。圧縮を行わないと、データを取得する人はそのうちの 1 つ、つまり非圧縮サイズのみを確認できます。
これではまだ圧縮ファイル内のデータにアクセスすることはできませんが、データに関するいくつかのヒントは得られます。あり得ない種類のデータを伝えることができます。 50% 圧縮されたファイルが表示された場合、そのファイルに MP4 圧縮ビデオが含まれている可能性は非常に低いです。
同様に、わずか数バイトに圧縮されたファイルには、非常に単純な繰り返しシーケンスが含まれる可能性があります。シーケンスが何であるかを知ることはできませんが、可能性は低くなります。 RELEASE.2022-07-13T23-29-44Zの MinIO は、圧縮出力を 256 バイトの倍数にパディングします。このパディングはどこにも記録されません。これが問題の完全な修正であるとは考えていませんが、攻撃者にとって漏洩したサイズ情報の有用性は大幅に低下します。
これが、MinIO が圧縮サイズに関する情報をクライアントに返さない主な理由です。したがって、これに関する情報はバックエンド ストレージまたはバックエンド ネットワーク通信にアクセスする必要があります。
この情報により、圧縮と暗号化を有効にしても安全かどうかを判断するための十分な知識が得られます。
MinIO では圧縮ストリームの変更や追加が許可されていないため、 CRIMEスタイルの攻撃は不可能です。また、ファイルに関する情報が多量に漏洩する可能性があるため、オブジェクトのバージョン間での重複排除/圧縮も行いません。
デフォルトでは、MinIO ではディスク上の圧縮が無効になっています。ディスク上の圧縮はいつでも有効または無効にできます。ディスク上の圧縮を有効にするには、 mc admin config set myminio compression enable=on
使用します。
これにより、事前に設定された数の拡張子と MIME タイプの圧縮が有効になります。デフォルトでは、これらには次のものが含まれます。
拡張機能 | MIME タイプ |
---|---|
.txt.log.csv.json.tar.xml.bin | text/*application/jsonapplication/xmlbinary/octet-stream |
mc admin config get myminio compression
を使用して現在の設定を検査できます。
このリストは、以下を変更することでいつでも変更できます。
mc admin config set myminio compression \ extensions=.txt,.log,.csv,.json,.tar,.xml,.bin \ mime_types=text/*,application/json,application/xml,binary/octet-stream
デフォルトでは、MinIO は、gzip、オーディオ、ビデオ、画像ファイルなど、一般に圧縮できないデータの拡張子を強制的に除外します。
拡張子リストと MIME タイプを空に設定することで、除外されたオブジェクトを除くすべてのオブジェクトの圧縮を有効にすることができます。
mc admin config set myminio compression enable=on extensions= mime_types=
最後の設定は、 allow_encryption=on
、暗号化されるオブジェクトに対しても圧縮を許可します。これは、上記のセクションを読み、その意味を理解した場合にのみ設定してください。
MinIO は、ディスク上のデータを完全に透過的に圧縮できるクラス最高の圧縮スキームを提供します。これにより、多くのシナリオで、圧縮を有効にするだけでストレージ コストの削減につながります。
圧縮が有効になっている場合、GET および PUT のパフォーマンスはどのような場合でもほぼ同じままである必要があります。実際、ディスクの読み取り速度によってパフォーマンスが制限される状況では、圧縮によって読み取るデータが少なくなるため、パフォーマンスが向上する可能性があります。
今後も新しい機能を追加していきます。現在、バケット/プレフィックス レベルの構成オプションと、ファイルが一定の期限に達したときにファイルを圧縮するライフサイクル経由の圧縮を評価中です。
これらの機能に興味がある場合は、 MinIO をダウンロードして自分で試してみてください。ご質問がある場合、または MinIO を使用して構築している素晴らしいアプリについて教えていただきたい場合は、 [email protected]にメッセージを送信するか、 Slack コミュニティに参加するか、ブログをフォローするか、ニュースレターを購読してください。
ここでも公開されています。