2012-05-03 3 views
2

Выходные файлы, созданные моей операцией «Уменьшить», огромны (1 ГБ после Gzipping). Я хочу, чтобы он производил выход break в файлы размером 200 МБ. Есть ли свойство/класс Java для разделения сокращения вывода по размеру или нет. линий? Я не могу увеличить количество редукторов, потому что это отрицательно сказывается на производительности работы хауопа.Вывод выходного сигнала для разделения в Hadoop

ответ

2

Мне любопытно, почему вы не можете использовать больше редукторов, но я возьму вас на ваше слово.

Один из вариантов, который вы можете сделать, это использовать MultipleOutputs и записать в несколько файлов с одного редуктора. Например, скажем, что выходной файл для каждого редуктора составляет 1 ГБ, а вы хотите 256 МБ файлов. Это означает, что вам нужно записать 4 файла на редуктор, а не один файл.

В драйвере задания, выполните следующие действия:

JobConf conf = ...; 

// You should probably pass this in as parameter rather than hardcoding 4. 
conf.setInt("outputs.per.reducer", 4); 

// This sets up the infrastructure to write multiple files per reducer. 
MultipleOutputs.addMultiNamedOutput(conf, "multi", YourOutputFormat.class, YourKey.class, YourValue.class); 

В вашем редукторе, сделайте следующее: Код

@Override 
public void configure(JobConf conf) { 
    numFiles = conf.getInt("outputs.per.reducer", 1); 
    multipleOutputs = new MultipleOutputs(conf); 

    // other init stuff 
    ... 
} 

@Override 
public void reduce(YourKey key 
        Iterator<YourValue> valuesIter, 
        OutputCollector<OutKey, OutVal> ignoreThis, 
        Reporter reporter) { 
    // Do your business logic just as you're doing currently. 
    OutKey outputKey = ...; 
    OutVal outputVal = ...; 

    // Now this is where it gets interesting. Hash the value to find 
    // which output file the data should be written to. Don't use the 
    // key since all the data will be written to one file if the number 
    // of reducers is a multiple of numFiles. 
    int fileIndex = (outputVal.hashCode() & Integer.MAX_VALUE) % numFiles; 

    // Now use multiple outputs to actually write the data. 
    // This will create output files named: multi_0-r-00000, multi_1-r-00000, 
    // multi_2-r-00000, multi_3-r-00000 for reducer 0. For reducer 1, the files 
    // will be multi_0-r-00001, multi_1-r-00001, multi_2-r-00001, multi_3-r-00001. 
    multipleOutputs.getCollector("multi", Integer.toString(fileIndex), reporter) 
     .collect(outputKey, outputValue); 
} 

@Overrider 
public void close() { 
    // You must do this!!!! 
    multipleOutputs.close(); 
} 

Псевдо была написана со старой MapReduce АФИ в виду. Эквивалентная apis существует с использованием mapreduce api, хотя, так и в любом случае, вы должны быть настроены.

+0

Я не могу увеличить количество редукторов, потому что это замедляет работу, поскольку необходимо выполнить больше перетасовки данных. Я подтвердил это теоретически и на практике. Однако я предлагаю ваше решение. Я попробую. – hznut

0

Для этого нету собственности. Вам нужно будет написать собственный формат вывода & записи.

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