MapReduceアプリケーションは、 レコードごとに ベースで入力スプリットのデータを処理し、各レコードはMapReduceによって キー/値 対。入力スプリットが計算された後、マッパータスクはそれらの処理を開始できます。つまり、リソースマネージャのスケジューリング機能が処理リソースを割り当てた直後です。 (Hadoop 1では、JobTrackerはマッパータスクを特定の処理スロットに割り当てます。)
<! - 1 - >マッパー・タスク自体は、一度に1レコードずつ入力分割を処理します。この図では、この単独レコードはキーと値のペアで表されます。私たちの飛行データの場合、(テキストファイルのデフォルトのファイル処理方法を使用して)入力分割が計算されるとき、テキストファイルの各行は単一のレコードであると仮定します。
レコードごとに、行自体のテキストが値を表し、分割の先頭から各行のバイトオフセットがキーとみなされます。
バイトオフセットの代わりに行番号が使用されないのはなぜだろうか。非常に大きなテキストファイルが多くの個々のデータブロックに分割され、分割数が多いと考えられる場合、行番号は危険な概念です。
<! - 3 - >各分割内の行数が異なるため、処理中の行の数を計算することは不可能です。ただし、すべてのブロックには固定バイト数があるため、バイトオフセットを使用すると正確になります。
マッパータスクは各レコードを処理するので、新しいキーと値のペアを生成します。ここでキーと値は入力ペアとは完全に異なる場合があります。マッパータスクの出力は、これらのすべてのキーと値のペアの完全なコレクションです。
各マッパータスクの最終出力ファイルが書き込まれる前に、出力はキーに基づいて分割され、ソートされます。この分割は、各キーのすべての値が一緒にグループ化されることを意味します。
かなり基本的なサンプルアプリケーションの場合、単一のレデューサーしかないので、マッパータスクのすべての出力が1つのファイルに書き込まれます。しかし、複数のリデューサーがある場合、すべてのマッパータスクが複数の出力ファイルを生成することもあります。
これらの出力ファイルの内訳は、区分キーに基づいています。たとえば、マッパー・タスク用に3つの別個のパーティション化キーしか出力されておらず、そのジョブ用の3つのリデューサーを構成した場合は、3つのマッパー出力ファイルが存在します。この例では、特定のマッパータスクが入力分割を処理し、3つのキーのうちの2つを使用して出力を生成する場合、出力ファイルは2つだけになります。
マッパータスクの出力ファイルを常に圧縮します。より小さい出力ファイルを書くことは、減速器が動作しているノードにマッパー出力を転送する必然的なコストを最小限に抑えるので、ここでの最大の利点はパフォーマンスの向上です。
ほとんどの状況では、デフォルトのパーティショナーは十分ではありませんが、レデューサーによって処理される前にデータがどのように分割されるかをカスタマイズしたい場合があります。たとえば、結果セット内のデータを、キーとその値(セカンダリ ソート)でソートすることができます。 これを行うには、デフォルトのパーティショナーをオーバーライドし、独自のパーティショナーを実装します。ただし、このプロセスでは、各パーティションのレコード数が均一であることを確認する必要があるため、注意が必要です。 (あるレデューサーが他のレデューサーよりもはるかに多くのデータを処理する必要がある場合は、MapReduceジョブが完了するのを待っています。一方、過度に大きなレデューサーは、不均等に大きなデータセットによってスローされます)。 MapReduce処理で利用可能な並列処理をより有効に活用できます。