私の MR ジョブで、LZO への map または reduce 出力の圧縮を指定するとします。どのように圧縮されるのでしょうか? map または reduce タスクからのデータ全体が最初に圧縮なしで取得され、最後に圧縮されていないデータが圧縮されるか、それとも段階的に圧縮されて書き込まれるか。段階的に圧縮されて書き込まれる場合、どのように行われるのでしょうか? これを理解するのを手伝ってください。
ありがとう、
ベンカット
私の MR ジョブで、LZO への map または reduce 出力の圧縮を指定するとします。どのように圧縮されるのでしょうか? map または reduce タスクからのデータ全体が最初に圧縮なしで取得され、最後に圧縮されていないデータが圧縮されるか、それとも段階的に圧縮されて書き込まれるか。段階的に圧縮されて書き込まれる場合、どのように行われるのでしょうか? これを理解するのを手伝ってください。
ありがとう、
ベンカット
基本的に、使用するファイルの種類によって異なります。テキスト ファイルの場合、圧縮はファイル レベルで行われます。ただし、SequenceFile の場合、圧縮はレコード レベルまたはブロック レベルである可能性があります。ここでのブロックは、hdfs ブロックではなく、シーケンス ファイルを使用する際のバッファーを意味することに注意してください。
ブロック圧縮の場合、複数のレコードが一度にブロックに圧縮されます。ブロックが最小サイズ (バイト単位) に達するまで、レコードがブロックに追加されます。一度に圧縮される入力データの最大サイズは、バッファ サイズから圧縮アルゴリズムの最大オーバーヘッドを差し引いて計算されます。デフォルトのバッファ サイズは 512 バイトで、zlib アルゴリズムの圧縮オーバーヘッドは 18 バイト (bufferSize の 1% + 12 バイト) です。次に、指定された出力ストリームとコンプレッサーを使用して BlockCompressorStream が作成され、圧縮されたデータが書き込まれます。
これが質問にある程度答えることを願っています。
圧縮が mapreduce パイプラインのどこに適合するかをより高いレベルで説明することにより、Tariq の回答にもう少し詳細を追加すると思いました。うまくいけば、それは役に立ちます。
マップ ステージに圧縮を指定すると ( mapreduce.map.output.compress=true
)、中間マップ出力データは、指定したコーデックを使用して圧縮され ( mapreduce.map.ouput.compress.codec=org.apache.hadoop.io.compress.*
)、各マップ タスクの完了時に (またはマップ タスクがシリアライゼーション バッファーを超える場合はそれ以前に) ディスクに保存されます。制限し、ディスクにこぼれ始めます)。次に、圧縮されたデータがディスクから読み取られ、mapreduce ジョブの Shuffle & Sort ステージ中に適切なノードに送信されます。
この段階 (マップ出力) では、結果の圧縮は分割可能であることのメリットがないため、ここでは LZO や BZIP2 と同様に GZIP または Snappy コーデックを試す価値があります。通常、GZIP はほとんどのデータに対してより優れた圧縮率を持っていますが、CPU を大量に消費しますが、Snappy は圧縮率が低くても高速です (つまり、GZIP ほど遅延が少ないか、CPU を大量に消費しません)。理由)。Teragen から生成されたデータを使用すると、GZIP と Snappy の圧縮率はそれぞれ 3.5 倍と 2.5 倍です。明らかに、データとハードウェアの制限によって、状況に応じて最も有益なコーデックが決定されます。
shuffle & sort ステージの前に圧縮すると、ディスク IO が削減され、圧縮されたデータがネットワーク経由で送信されるため、ネットワーク帯域幅が削減されます。CPU リソースが競合していない限り、この段階でデータを圧縮しない正当な理由は思いつきません。私の小さな 10 ノードの Hadoop クラスターを 1 Gb ネットワークで実行している場合、マップ出力段階 (つまり、シャッフル & ソート段階の前の中間マップ データは圧縮され、最終出力は圧縮されません) だけ圧縮をオンにすると、全体のジョブ時間が改善されました。 100GB のテラソート ジョブで41% (GZIP)、および45% (Snappy)対圧縮を使用しない。これらの実験のデータは、teragen を使用して生成されました。もちろん、結果はデータセット、ハードウェア、およびネットワークによって異なります。
圧縮されたデータは、reduce フェーズの開始時に解凍されます。
圧縮は、最終出力 (mapreduce.output.fileoutputformat.compress=true) の削減フェーズの最後にもう一度行われます。出力を別の mapreduce ジョブにフィードする場合、分割可能な LZO または BZIP2 圧縮が役立つ場合があります。出力で分割可能な圧縮コーデックを使用せず、そのデータでジョブを実行すると、単一のマッパーしか使用できず、Hadoop の主な利点の 1 つが無効になります。並列化。これを回避し、GZIP コーデックなどを使用する 1 つの方法は、出力用のシーケンス ファイルを作成することです。シーケンス ファイルは、基本的に一連の圧縮ファイルが一緒に追加されているため、分割可能です。シーケンス ファイルは、各ファイルが他のファイルに追加される境界で分割可能です。