Как указать разделитель KeyValueTextInputFormat в Hadoop-.20 API? - PullRequest
13 голосов
/ 09 февраля 2012

В новом API (apache.hadoop.mapreduce.KeyValueTextInputFormat), как указать разделитель (разделитель), кроме табуляции (по умолчанию), для разделения ключа и значения.

Пример ввода:

one,first line
two,second line

Требуется выход:

Key : one
Value : first line
Key : two
Value : second line

Я указываю KeyValueTextInputFormat как:

    Job job = new Job(conf, "Sample");

    job.setInputFormatClass(KeyValueTextInputFormat.class);
    KeyValueTextInputFormat.addInputPath(job, new Path("/home/input.txt"));

Это нормально работает для табуляции в качестве разделителя.

Ответы [ 7 ]

11 голосов
/ 10 апреля 2013

В более новом API вы должны использовать mapreduce.input.keyvaluelinerecordreader.key.value.separator свойство конфигурации.

Вот пример:

Configuration conf = new Configuration();
conf.set("mapreduce.input.keyvaluelinerecordreader.key.value.separator", ",");

Job job = new Job(conf);
job.setInputFormatClass(KeyValueTextInputFormat.class);
// next job set-up
5 голосов
/ 10 февраля 2012

Пожалуйста, установите следующее в коде драйвера.

conf.set("key.value.separator.in.input.line", ",");
1 голос
/ 02 января 2016

Это вопрос последовательности.

Первая строка conf.set("key.value.separator.in.input.line", ",") должна появиться перед созданием экземпляра класса Job. Итак:

conf.set("key.value.separator.in.input.line", ","); 
Job job = new Job(conf);
1 голос
/ 29 сентября 2014

Для KeyValueTextInputFormat строка ввода должна представлять собой пару значений ключа, разделенных "\ t"

Key1     Value1,Value2

Сменив разделитель по умолчанию, Вы сможете читать по своему усмотрению.

Для нового API

Вот решение

//New API
Configuration conf = new Configuration();
conf.set("key.value.separator.in.input.line", ","); 
Job job = new Job(conf);
job.setInputFormatClass(KeyValueTextInputFormat.class);

Карта

public class Map extends Mapper<Text, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();

public void map(Text key, Text value, Context context)
        throws IOException, InterruptedException {
    String line = value.toString();
    System.out.println("key---> "+key);
    System.out.println("value---> "+value.toString());
   .
   .

выход

key---> one
value---> first line
key---> two
value---> second line
0 голосов
/ 11 декабря 2018

Пример

public class KeyValueTextInput extends Configured implements Tool {
    public static void main(String args[]) throws Exception {
        String log4jConfPath = "log4j.properties";
        PropertyConfigurator.configure(log4jConfPath);
        int res = ToolRunner.run(new KeyValueTextInput(), args);
        System.exit(res);
    }

    public int run(String[] args) throws Exception {

Конфигурация conf = this.getConf ();

        //conf.set("key.value.separator.in.input.line", ",");

conf.set ( "mapreduce.input.keyvaluelinerecordreader.key.value.separator", "");

        Job job = Job.getInstance(conf, "WordCountSampleTemplate");
        job.setJarByClass(KeyValueTextInput.class);
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);

        //job.setMapOutputKeyClass(Text.class);
        //job.setMapOutputValueClass(Text.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        job.setInputFormatClass(KeyValueTextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        Path outputPath = new Path(args[1]);
        FileSystem fs = FileSystem.get(new URI(outputPath.toString()), conf);
        fs.delete(outputPath, true);
        FileOutputFormat.setOutputPath(job, outputPath);
        return job.waitForCompletion(true) ? 0 : 1;
    }
}

class Map extends Mapper<Text, Text, Text, Text> {
    public void map(Text k1, Text v1, Context context) throws IOException, InterruptedException {
        context.write(k1, v1);
    }
}

class Reduce extends Reducer<Text, Text, Text, Text> {
    public void reduce(Text Key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
        String sum = " || ";
        for (Text value : values)
            sum = sum + value.toString() + " || ";
        context.write(Key, new Text(sum));
    }
}
0 голосов
/ 03 апреля 2014

По умолчанию класс KeyValueTextInputFormat использует вкладку в качестве разделителя для ключа и значения из входного текстового файла.

Если вы хотите прочитать входные данные из пользовательского разделителя, то вам нужно установить конфигурациюс атрибутом, который вы используете.

Для новых API Hadoop он отличается:

conf.set("mapreduce.input.keyvaluelinerecordreader.key.value.separator", ";");
0 голосов
/ 10 февраля 2012

Во-первых, новый API не завершился в 0.20. *, Поэтому, если вы хотите использовать новый API в 0.20. *, Вы должны реализовать эту функцию самостоятельно. Например, вы можете использовать FileInputFormat для достижения.Игнорируйте ключ LongWritable и разбивайте текстовое значение на запятую самостоятельно.

...