0

複数の入力ソースがあり、Sqoop の codegen ツールを使用して各入力ソースのカスタム クラスを生成しました。

public class SQOOP_REC1 extends SqoopRecord  implements DBWritable, Writable

public class SQOOP_REC2 extends SqoopRecord  implements DBWritable, Writable

Map 側では、入力ソースに基づいて、上記の 2 つのクラスのオブジェクトを適宜作成します。

キーは「テキスト」タイプで、2 つの異なるタイプの値があるため、値の出力タイプを「書き込み可能」のままにしました。

reduce 側では、値の型を Writable として受け入れます。

   public class SkeletonReduce extends Reducer<Text,Writable, Text, Text> {

public void reduce(Text key, Iterable<Writable> values, Context context) throws     IOException,InterruptedException {

   }
}

私も設定しました

job.setMapOutputValueClass(Writable.class);

実行中はreduce関数には一切入りません。

これが可能かどうか誰かに教えてもらえますか?もしそうなら、私は何を間違っていますか?

4

3 に答える 3

0

値の型の GenericWritable を拡張することを検討してください。許可されているクラスのセット (あなたの場合は SQOOP_REC1 と SQOOP_REC2) を定義する必要がありますが、readFields メソッドで新しいオブジェクト インスタンスを作成するため効率的ではありません (ただし、クラスのセットが小さい場合はこれをオーバーライドできます。両方のタイプのインスタンス変数と、どちらが有効かを示すフラグを持つだけです)

于 2012-04-24T13:01:24.143 に答える
0

わかりました、これを行う方法を理解したと思います。Doug Cutting 自身の提案に基づく

http://grokbase.com/t/hadoop/common-user/083gzhd6zd/multiple-output-value-classes

ObjectWritable を使用してクラスをラップしました

ObjectWritable obj = new ObjectWritable(SQOOP_REC2.class,sqoop_rec2);

次に、Reduce 側で、ラップされたクラスの名前を取得し、それを元のクラスにキャストできます。

if(val.getDeclaredClass().getName().equals("SQOOP_REC2")){
                SQOOP_REC2temp = (SQOOP_REC2) val.get();

忘れないで

        job.setMapOutputValueClass(ObjectWritable.class);
于 2012-04-25T05:21:37.107 に答える
0

Writable出力タイプとして指定することはできません。具象型でなければなりません。すべてのレコードは、Mappers とReducers で同じ (具体的な) キーと値の型を持つ必要があります。Writable異なるタイプが必要な場合は、「A」または「B」を内部に含むある種のハイブリッドを作成できます。それは少し醜いですが、機能し、たとえば Mahout で多く行われています。

しかし、これが原因でレデューサーが実行されない理由がわかりません。これはおそらくまったく別のものであり、この情報に基づいて答えることはできません.

于 2012-04-24T12:38:35.373 に答える