hadoop конвертирует \r\n в \ n и нарушает формат ARC
Я пытаюсь проанализировать данные с commoncrawl.org с помощью потоковой передачи hadoop. Я настроил локальный hadoop для тестирования своего кода, и у меня есть простой Ruby Mapper, который использует потоковый читатель ARCfile. Когда я вызываю свой код сам, как
cat 1262876244253_18.arc.gz | mapper.rb | reducer.rb
Работает как положено.
Кажется, что hadoop автоматически видит, что файл имеет расширение.gz, и распаковывает его перед передачей его в маппер - однако при этом он преобразует \r\n переносы строк в потоке в \n. Поскольку ARC зависит от длины записи в строке заголовка, изменение нарушает синтаксический анализатор (поскольку длина данных изменилась).
Чтобы перепроверить, я изменил свой маппер, чтобы ожидать несжатых данных, и сделал:
cat 1262876244253_18.arc.gz | zcat | mapper.rb | reducer.rb
И это работает.
Я не возражаю против автоматического распаковывания hadoop (хотя я вполне могу справиться с потоковой передачей файлов.gz), но если это необходимо, мне нужно распаковать его в "бинарный", не выполняя преобразования строки или подобного. Я полагаю, что по умолчанию используется подача распакованных файлов по одному мапперу на файл, что идеально.
Как я могу попросить его не распаковывать.gz (переименование файлов не вариант) или заставить его распаковать правильно? Я бы предпочел не использовать специальный класс InputFormat, который я должен отправить в банке, если это вообще возможно.
В конечном итоге все это будет работать на AWS ElasticMapReduce.
1 ответ
Похоже, виноват Hadoop PipeMapper.java (по крайней мере, в 0.20.2):
Вокруг строки 106 ввод из TextInputFormat передается этому преобразователю (на этом этапе \r\n был удален), и PipeMapper записывает его в стандартный вывод просто с помощью \n.
Было бы предложено изменить исходный код для вашего PipeMapper.java, проверить, что эта "функция" все еще существует, и изменить по мере необходимости (возможно, разрешить ее установку через свойство конфигурации).