У меня есть SequenceFile, созданный из предыдущего задания MapReduce. Этот SequenceFile состоит из N строк, каждая строка представляет собой пару ключ и значение, оба являются текстовыми объектами.
line1: key1 \t value1
line2: key2 \t value2
line3: key3 \t value3
...
lineN: keyN \t valueN
Я использую этот SequenceFile в качестве входных данных для нового задания MapReduce. В этом новом задании MapReduce я хочу, чтобы каждый преобразователь обрабатывал несколько строк, например, 2 строки этого SequenceFile, например.
line1, line2 goes to mapper1
line3, line4 goes to mapper2
.....
line(N-1), lineN goes to mapperN
Я не мог использовать NLineInputFormat, потому что он используется только для текстового файла. Итак, я использовал SequenceFileInputFormat и позволил Hadoop разделить данные на 40 МБ каждый (мой размер блока = 40 МБ). Несмотря на то, что все разбиения одинаковы по размеру, есть преобразователи, которые получают гораздо больше данных (т. е. строк), чем другие. Например, 5 строк идут на mapper1, а только 1 строка идет на mapper2. Таким образом, mapper2 завершается очень быстро, в то время как mapper1 занимает очень много времени, и много раз он терпит неудачу из-за переполнения кучи Java.
Я пробовал следующее, но ни один из них не работал:
- Изменить размер блока:
- Увеличьте количество картографов: проблема все та же. Многие мапперы заканчивают работу очень быстро, потому что нет строки ввода, в то время как некоторые мапперы берут почти ввод и никогда не заканчивают.
- Преобразуйте мой файл SequenceFile в текстовый файл, а затем используйте NLineInputFormat: размер кучи Java переполняется из-за того, что текстовый файл занимает слишком много оперативной памяти. Вот почему я хочу использовать SequenceFile, потому что он поддерживает сжатие.
Мой вопрос:
Как заставить каждый преобразователь получить одинаковое (или эквивалентное) количество входных строк файла SequenceFile?