異なるマッパーが同じ入力ファイル、つまり同じデータ構造を消費する場合、これらすべての異なるマッパーのソースコードを単一のマッパー実装の別々のメソッドに配置し、コンテキストのパラメーターを使用して、呼び出すマップ関数を決定できます。 。プラス面では、1つのMapReduceジョブのみを開始する必要があります。例は擬似コードです:
class ComplexMapper extends Mapper {
protected BitSet mappingBitmap = new BitSet();
protected void setup(Context context) ... {
{
String params = context.getConfiguration().get("params");
---analyze params and set bits into the mappingBitmap
}
protected void mapA(Object key, Object value, Context context){
.....
context.write(keyA, value);
}
protected void mapB(Object key, Object value, Context context){
.....
context.write(keyA, value);
}
protected void mapB(Object key, Object value, Context context){
.....
context.write(keyB, value);
}
public void map(Object key, Object value, Context context) ..... {
if (mappingBitmap.get(1)) {
mapA(key, value, context);
}
if (mappingBitmap.get(2)) {
mapB(key, value, context);
}
if (mappingBitmap.get(3)) {
mapC(key, value, context);
}
}
当然のことながら、インターフェースなどを使用してよりエレガントに実装できます。
ジョブの設定で、次を追加するだけです。
Configuration conf = new Configuration();
conf.set("params", "AB");
Job job = new Job(conf);
Praveen Sripatiが述べたように、出力ファイルが1つであると、Reducerが1つだけになり、パフォーマンスが低下する可能性があります。hdfsからダウンロードする場合は、いつでもpart**ファイルを連結できます。例:
hadoop fs -text /output_dir/part* > wholefile.txt