これは、Hadoop/HDFSに関する概念的な質問です。 10億行を含むファイルがあるとします。また、簡単にするために、各行の形式が<k,v>
ここで、kは行の先頭からのオフセットで、valueは行の内容です。
ここで、N個のマップタスクを実行するという場合、フレームワークは入力ファイルをN個の分割に分割し、その分割で各マップタスクを実行しますか?または、N個の分割を行い、生成された分割で各マップタスクを実行するパーティション関数を作成する必要がありますか?
私が知りたいのは、分割が内部的に行われるか、データを手動で分割する必要があるかです。
より具体的には、map()関数が呼び出されるたびに、そのKey key and Value val
パラメーター?
ありがとう、ディーパック
InputFormat
は、分割を提供する役割を果たします。
一般に、n個のノードがある場合、HDFSはこれらすべてのn個のノードにファイルを配布します。ジョブを開始すると、デフォルトでn個のマッパーが存在します。 Hadoopのおかげで、マシンのマッパーがこのノードに保存されているデータの一部を処理します。これはRack awareness
。
要するに、HDFSにデータをアップロードし、MRジョブを開始します。 Hadoopは最適化された実行を処理します。
ファイルはHDFSブロックに分割され、ブロックが複製されます。 Hadoopは、データの局所性の原則に基づいて、分割にノードを割り当てます。 Hadoopは、ブロックが存在するノードでマッパーを実行しようとします。複製のため、同じブロックをホストするこのようなノードが複数あります。
ノードが利用できない場合、Hadoopはデータブロックをホストするノードに最も近いノードを選択しようとします。たとえば、同じラック内の別のノードを選択できます。ノードはさまざまな理由で利用できない場合があります。すべてのマップスロットが使用中であるか、ノードが単にダウンしている可能性があります。
幸いなことに、すべてがフレームワークによって処理されます。
MapReduceデータ処理は、この概念input splitsによって駆動されます。特定のアプリケーションに対して計算される入力分割の数によって、マッパータスクの数が決まります。
通常、マップの数は、入力ファイル内のDFSブロックの数によって決まります。
これらの各マッパータスクは、可能であれば、入力分割が保存されているスレーブノードに割り当てられます。リソースマネージャー(またはHadoop 1を使用している場合はJobTracker)は、入力分割がローカルで処理されるように最善を尽くします。
data localityがデータノードの境界を越える入力分割のために達成できない場合、一部のデータ1つのデータノードから他のデータノードに転送されます。
128 MBのブロックがあり、最後のレコードがBlock aに収まらず、Block b、それからBlock bのデータはBlock a
この図をご覧ください。
関連する質問をご覧ください
InputSplitsがhadoopでどのように機能するかをよりよく理解するには、 ダミーのためにhadoopが書いた記事 を読むことをお勧めします。本当に助かります。
Deepakが求めていたのは、各マップに存在するデータではなく、マップ関数の各callの入力がどのように決定されるかについてだったと思うnode。私は質問の2番目の部分に基づいてこれを言っています:より具体的には、map()関数が呼び出されるたびに、そのキーキーと値valパラメータは何ですか?
実際、同じ質問が私をここに連れてきて、私が経験豊富なhadoop開発者だったなら、上の答えのように解釈したかもしれません。
質問に答えるために、
特定のマップノードのファイルは、InputFormatに設定した値に基づいて分割されます。 (これはJava using setInputFormat() !で行われます))
例:
conf.setInputFormat(TextInputFormat.class);ここでは、TextInputFormatをsetInputFormat関数に渡すことで、マップノードの入力ファイルの各lineをマップへの入力として扱うようhadoopに指示しています。関数。改行またはキャリッジリターンを使用して、行末を通知します。詳細は TextInputFormat !
この例では、キーはファイル内の位置であり、値はテキストの行です。
お役に立てれば。
Hadoopジョブが実行されると、入力ファイルがチャンクに分割され、各分割がマッパーに割り当てられて処理されます。これはInputSplitと呼ばれます。
FileInputFormatは、入力ファイルの読み取り方法とスピルアップ方法を定義する抽象クラスです。 FileInputFormatは、次の機能を提供します。1.入力として使用するファイル/オブジェクトを選択します2.ファイルをタスクに分割する入力スプリットを定義します。
Hadooppの基本機能ごとに、n個のスプリットがある場合、n個のマッパーがあります。
ブロックサイズと入力分割サイズの違い
入力分割は、データの論理的な分割であり、基本的にMapReduceプログラムでのデータ処理またはその他の処理手法で使用されます。入力分割サイズはユーザー定義の値であり、Hadoop Developerはデータのサイズ(処理しているデータの量)に基づいて分割サイズを選択できます。
入力分割は、基本的にMapReduceプログラムでマッパーの数を制御するために使用されます。 MapReduceプログラムで入力分割サイズを定義していない場合、データ処理中にデフォルトのHDFSブロック分割が入力分割と見なされます。
例:
100MBのファイルがあり、HDFSのデフォルトのブロック構成が64MBである場合、2つの分割に分割され、2つのHDFSブロックを占有するとします。このデータを処理するMapReduceプログラムがありますが、入力分割を指定していない場合、ブロック数に基づいて(2ブロック)MapReduce処理の入力分割と見なされ、2つのマッパーがこのジョブに割り当てられます。ただし、MapReduceプログラムで分割サイズ(100MBなど)を指定した場合、両方のブロック(2ブロック)がMapReduce処理の単一の分割と見なされ、1つのMapperがこのジョブに割り当てられます。
MapReduceプログラムで分割サイズ(25MBなど)を指定した場合、MapReduceプログラムに4つの入力分割があり、4つのMapperがジョブに割り当てられるとします。
結論:
ソース: https://hadoopjournal.wordpress.com/2015/06/30/mapreduce-input-split-versus-hdfs-blocks/
簡単な答えは、InputFormatがファイルの分割を処理することです。
この質問にアプローチする方法は、デフォルトのTextInputFormatクラスを見ることです。
InputFormatクラスはすべてFileInputFormatのサブクラスであり、分割を処理します。
具体的には、FileInputFormatのgetSplit関数は、JobContextで定義されたファイルのリストからInputSplitのリストを生成します。分割はバイトのサイズに基づいており、その最小値と最大値はプロジェクトxmlファイルで任意に定義できます。
ファイルをブロックに分割する個別のマップ削減ジョブがあります。大きなファイルにはFileInputFormatを使用し、小さなファイルにはCombineFileInput Formatを使用します。 issplittableメソッドを使用して、入力をブロックに分割できるかどうかも確認できます。その後、各ブロックはデータノードに送られ、マップ分析ジョブがさらに分析するために実行されます。ブロックのサイズは、mapred.max.split.sizeパラメーターで言及したサイズに依存します。
FileInputFormat.addInputPath(job、new Path(args [0]));または
conf.setInputFormat(TextInputFormat.class);
class FileInputFormat funcation addInputPath、setInputFormat inputsplitを処理し、このコードは作成されるマッパーの数を定義します。 inputsplitと言えます。マッパーの数は、HDFSに入力ファイルを保存するために使用されるブロックの数に正比例します。
例サイズが74 Mbの入力ファイルがある場合、このファイルはHDFSに2ブロック(64 MBおよび10 Mb)で保存されます。したがって、このファイルのinputsplitは2つであり、この入力ファイルを読み取るために2つのマッパーインスタンスが作成されます。