web-dev-qa-db-ja.com

Hadoopでのマッパー入力Key-Valueペア

通常、マッパーは次の形式で記述します。

public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable>

ここで、マッパーの入力Key-Valueペアは<LongWritable, Text>です-マッパーが入力データを取得すると、行ごとに入力データを取得します-したがって、マッパーのキーは行番号を示します-修正してください私が間違っている場合。

私の質問は、マッパーの入力キーと値のペアを<Text, Text>として指定すると、エラーが発生します

 Java.lang.ClassCastException: org.Apache.hadoop.io.LongWritable cannot be cast to org.Apache.hadoop.io.Text

マッパーの入力Key-Valueペアを<LongWritable, Text>として指定することは必須ですか?はいの場合、なぜですか?いいえの場合、エラーの理由は何ですか?エラーの適切な理由を教えてください。

前もって感謝します。

12
Ronin

マッパーへの入力は、使用されるInputFormatによって異なります。 InputFormatは、着信データを読み取り、マッパーが期待する形式に整形します。デフォルトのInputFormatは TextInputFormat で、FileInputFormat<LongWritable, Text>を拡張します。

InputFormatを変更しない場合、<LongWritable, Text>とは異なるKey-Valueタイプシグネチャを持つマッパーを使用すると、このエラーが発生します。 <Text, Text>入力が必要な場合は、適切なInputFormatを選択する必要があります。ジョブの設定でInputFormatを設定できます。

job.setInputFormatClass(MyInputFormat.class);

そして、私が言ったように、これはデフォルトでTextInputFormatに設定されています。

ここで、入力データが、コンマで区切られた改行で区切られた一連のレコードであるとします。

  • 「A、value1」
  • 「B、value2」

マッパーへの入力キーを( "A"、 "value1")、( "B"、 "value2")にする場合は、<Text, Text>シグネチャを使用してカスタムInputFormatおよびRecordReaderを実装する必要があります。 幸いにも、これはかなり簡単です。 ここの例 があり、おそらくいくつかの例もStackOverflowの周りに浮かんでいます。

つまり、FileInputFormat<Text, Text>を拡張するクラスとRecordReader<Text, Text>を拡張するクラスを追加します。 FileInputFormat#getRecordReaderメソッドをオーバーライドして、カスタムRecordReaderのインスタンスを返すようにします。

次に、必要なRecordReaderロジックを実装する必要があります。これを行う最も簡単な方法は、カスタムRecordReaderに LineRecordReader のインスタンスを作成し、すべての基本的な責任をこのインスタンスに委任することです。 getCurrentKeyメソッドとgetCurrentValueメソッドでは、LineRecordReader#getCurrentValueを呼び出してコンマで区切られたテキストコンテンツを抽出し、コンマで分割するロジックを実装します。

最後に、上記の2番目の段落の後に示すように、新しいInputFormatをJob InputFormatとして設定します。

30
Alex A.

トムホワイトの本「Hadoop:The Difinitive Guide」では、彼はこれに対して適切な答えを持っていると思います(197ページ)。

「TextInputFormatのキーは、単にファイル内のオフセットであるため、通常はあまり役に立ちません。ファイル内の各行が、タブ文字などの区切り文字で区切られたキーと値のペアであることが一般的です。たとえば、これはTextOutputFormatによって生成された出力、HadoopのデフォルトのOutputFormatこのようなファイルを正しく解釈するには、KeyValueTextInputFormatが適切です。

Key.value.separator.in.input.lineプロパティを介してセパレータを指定できます。デフォルトではタブ文字です。」

1
canada11