3

出力値が次のようなインターフェイスに設定されているマッパーがあります。

public interface OutValue extends Writable {}

マッピング中に、このシグネチャを使用してオブジェクトを作成し、それらを発行します。

public class OutRecord implements OutValue {}

私のマッパーは次のようなものです:

public class ExampleMapper extends
    Mapper<LongWritable, Text, ExampleKey, OutValue > {}

しかし、私はこのエラーが発生しています:

java.io.IOException: Type mismatch in value from map: expected OutValue, recieved OutRecord
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:850)
    at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:541)
    at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)

だから私の最初の本能は、次のようにキャストしようとすることでした:

context.write(key, (OutValue) record);

ただし、それでも同じエラーが発生します。これは、マッパーの出力タイプを OutRecord クラスから OutValue インターフェイスに変更する前に機能しました。そうする理由は、このマッパーから出力したい OutRecord クラスのタイプがたくさんあるからです。

これは可能ですか?OutValue はインターフェイスではなくクラスである必要がありますか?

アップデート:

Hadoop 0.20.205.0 のソースの一部を掘り下げたところ、次のことがわかりました。

public synchronized void collect(K key, V value, int partition) throws IOException {
...
if (value.getClass() != valClass) {
  throw new IOException("Type mismatch in value from map: expected "
                        + valClass.getName() + ", recieved "
                        + value.getClass().getName());
}

したがって、彼らが使用している実行時チェックは、クラス内で厳密な等価性を必要とし、サブクラス化/インターフェースなどをチェックしません。確かにこれは一般的なユースケースです。誰かがこれをやろうとしましたか?

4

1 に答える 1

2

このように型を厳密にチェックする理由はいくつかあります。

シーケンス ファイルに出力する場合、このファイルのヘッダーには Key クラスと Value クラスの型が含まれます。その後、Hadoop は、登録されたシリアライザーを使用して、シーケンス ファイルが読み戻されるときにこれらのオブジェクトの新しいインスタンスを作成します。

出力型として登録するクラスがインターフェイスである場合、または出力する実際のオブジェクトが宣言された型のサブクラスである場合、実行時にインターフェイスをインスタンス化できないか、インスタンス化されたクラスがサブクラスになりません。期待しているクラスです (そして、デシリアライズはおそらく IOException で失敗します)。

(これを入力し始めたとき、別の理由が頭に浮かびましたが、当分の間、それは私を逃れました)。

異なるタイプ (サブクラス) を出力できるようにしたい場合は、GenericWritableを使用してオブジェクトを「ラップ」することを検討してください

これには多少のコストがかかることに注意してください。入力と出力は、hadoop の他の場所で見られるオブジェクトの再利用を利用しませんが、このコストに気付かない場合があります。表示されるインスタンス タイプごとにオブジェクトをプールし、それを通常の方法で再利用することにより、GenericWritable をより効率的に書き直すことができます。

于 2012-06-21T00:57:23.370 に答える