Как спроектировать каждый преобразователь для обработки каждой строки SequenceFile?

У меня есть 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?


person cdt    schedule 12.06.2018    source источник
comment
Вы не можете контролировать линии, идущие к преобразователям, если каждая строка не имеет размер, точно равный размеру блока HDFS. Сколько у вас оперативной памяти и какие настройки YARN вы задаете для каждого контейнера?   -  person OneCricketeer    schedule 12.06.2018
comment
У меня есть кластер из 5 узлов, каждый из них имеет 8Gb RAM. Каждой ноде я отдал 6.4Gb под контейнер. Я думаю, что я не могу увеличить больше.   -  person cdt    schedule 12.06.2018
comment
Вы действительно хотите только одну возможную попытку mapreduce для каждого узла?   -  person OneCricketeer    schedule 12.06.2018
comment
Я пробовал с более низкими настройками Yarn, такими как 3 ГБ, 4 ГБ, но произошло переполнение кучи Java. Поэтому я увеличил до 6.4Gb.   -  person cdt    schedule 13.06.2018
comment
Можете ли вы помочь мне объяснить, что даже ввод каждого маппера составляет 40 МБ, но почему все еще есть мапперы, которые не получают входной строки? Я изменил размер блока на другой (30 МБ, 50 МБ, 80 МБ, 128 МБ...), такие мапперы все еще существовали.   -  person cdt    schedule 13.06.2018
comment
Вы перезалили файлы после изменения размера блока? Начальные блоки не меняются после редактирования конфигов. Лично я не знаю, как изменение этого значения повлияет на мапперов, так как я всегда оставлял значение по умолчанию.   -  person OneCricketeer    schedule 13.06.2018
comment
Конечно, я перезагрузил файл. Я изменил размер блока в надежде, что меньший блок будет вводиться в преобразователь --› преобразователь должен обрабатывать меньше --› не произойдет переполнения размера кучи Java. Но я был неправ. По какой-то причине многие данные по-прежнему поступают в определенный преобразователь, в то время как другие преобразователи не получают данных. Таким образом, переполнение размера кучи java все еще происходило.   -  person cdt    schedule 13.06.2018
comment
Вы не можете контролировать, сколько строк передается конкретному преобразователю, но вы можете контролировать, какие данные передаются какому редюсеру. Вы можете изменить свой маппер, чтобы просто передавать данные. Затем создайте свой собственный разделитель, который будет равномерно разделять данные на редукторы. Затем выполните логику, которая требует много оперативной памяти в редюсере.   -  person Luk    schedule 13.06.2018
comment
В этом есть смысл. Спасибо, Лук.   -  person cdt    schedule 13.06.2018


Ответы (1)


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

person Luk    schedule 13.06.2018