2014-02-11 4 views
3

У меня есть данные в формате csv.Как сгенерировать несколько имен файлов во время выполнения в HADOOP?

например, K1, K2, data1, data2, Data3

здесь мой картографа передает ключ к редуктору как k1k2 & Значение как DATA1, data2, Data3

Я хотел, чтобы сохранить эти данные в нескольких файлах с именем файла K1k2 (или ключом, который получает редуктор). Теперь, если я использую класс MultipleOutputs, я должен упомянуть имена файлов до начала отображения. Но здесь, поскольку только после прочтения данных из картографа, я могу определить ключ. Как мне продолжать?

PS Я новичок в этом.

ответ

0

Вы можете создавать имена файлов и передавать их MultipleOutputs в редукторе, как это:

public void setup(Context context) { 
    out = new MultipleOutputs(context); 
    ... 
} 

public void reduce(Text key, Iterable values, Context context) throws IOException,   InterruptedException { 
    for (Text t : values) { 
    out.write(key, t, generateFileName(<parameter list...>)); 
    // generateFileName is your function 
    } 
} 

protected void cleanup(Context context) throws IOException, InterruptedException { 
    out.close(); 
} 

Для получения более подробной информации читайте MultipleOutputs ссылки на класс: https://hadoop.apache.org/docs/current2/api/org/apache/hadoop/mapreduce/lib/output/MultipleOutputs.html

+0

Нет, но он дает java.lang.IllegalArgumentException об ошибке: Названы выход «K1K2» не определен \t в org.apache.hadoop.mapreduce.lib.output.MultipleOutputs. checkNamedOutputName (MultipleOutputs.java:193) – Sanchit

+0

Если я добавляю MultipleOutputs.addNamedOutput (job, FileName1.toString(), TextOutputFormat.class, NullWritable.class, Text.class); в методе generateOutput(), как мне получить работу в редукторе. Я только начал, что это может быть очень простой вопрос? – Sanchit

+0

нет необходимости в именованном выходе. просто посмотрите на мой пост –

-1

Нет необходимости предопределить имена выходных файлов .Здесь вы можете использовать MultipleOutputs вот так.

public class YourReducer extends Reducer<Text, Value, Text, Value> { 
private Value result = null; 
private MultipleOutputs<Text,Value> out; 

public void setup(Context context) { 
    out = new MultipleOutputs<Text,Value>(context);  
} 
public void reduce(Text key, Iterable<Value> values, Context context) 
     throws IOException, InterruptedException { 
    // do your code 
    out.write(key, result,"outputpath/"+key.getText());     
} 
public void cleanup(Context context) throws IOException,InterruptedException { 
    out.close();   
} 

}

Здесь он дает выход в следующих путей как

outputpath/K1 
      /K2 
      /K3 
....... 

Для этого вы должны использовать LazyOutputFormat.setOutputFormatClass() вместо FileOutputFormat. Также необходимо добавить конфигурацию задания как job.setOutputFormatClass(NullOutputFormat.class). Но не забудьте указать входные и выходные пути, используя FileOutputFormat.setOutputPath() и FileOutputFormat.setOutputPath(), как и раньше. Затем сгенерированные файлы будут относительно указанного OutputPath

+0

... и вам нужно определить MultipleOutputs в вашем «драйвере», который запускает задание. верный? – OhadR

+0

Что вы подразумеваете, определяя множественные выходы и драйвер? –

+0

файл, который запускает задание, вам нужно вызвать MultipleOutputs.addNamedOutput (job, ..., TextOutputFormat.class, ...) – OhadR

Смежные вопросы