2013-10-27 6 views
11

Нормально, мы пишем картографа в виде:Mapper вход пару ключ-значение в Hadoop

public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable> 

Здесь входной ключ-значение пара для картографа является <LongWritable, Text> - насколько я знаю, когда картографа получает входные данные его проходят по строке за строкой - так что Ключ для картографа означает номер строки - пожалуйста, исправьте меня, если я ошибаюсь.

Мой вопрос: Если я дам пару входной ключ-значение для картографа, как <Text, Text> то он дает ошибку

java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text 

Является ли это обязательным, чтобы дать входной ключ-значение пары картографа в <LongWritable, Text> - если да, то почему? если нет, то в чем причина ошибки? Можете ли вы, пожалуйста, помочь мне понять правильную причину ошибки?

Заранее спасибо.

+0

Не обязательно использовать 'LongWritable' в качестве ключа , Что вы делаете для создания этого исключения? Где это происходит в вашем коде? – Vidya

+0

Я не делаю ничего явно, чтобы сгенерировать это исключение - IT показывает :: java.lang.ClassCastException: org.apache.hadoop.io.LongWritable нельзя отнести к org.apache.hadoop.io.Text в ExamTest $ Map.map (ExamTest.java:1) на org.apache.hadoop.mapreduce.Mapper.run (Mapper.java:144) на org.apache.hadoop.mapred.MapTask.runNewMapper (MapTask.java:764) at org.apache.hadoop.mapred.MapTask.run (MapTask.java:370) at org.apache.hadoop.mapred.Child $ 4.run (Child.java:255) – Ronin

+0

Не могли бы вы объяснить ситуацию? Спасибо. – Ronin

ответ

30

Вход в устройство отображения зависит от того, что используется InputFormat. InputFormat отвечает за чтение входящих данных и формирование их в любом формате, который ожидает Mapper. По умолчанию InputFormat равен TextInputFormat, который расширяет FileInputFormat<LongWritable, Text>.

Если вы не меняете InputFormat, используйте Mapper с различной сигнатурой типа Key-Value, чем <LongWritable, Text>, что приведет к этой ошибке. Если вы ожидаете ввода <Text, Text>, вам нужно будет выбрать подходящий InputFormat. Вы можете установить InputFormat в настройке работы:

job.setInputFormatClass(MyInputFormat.class); 

И как я уже сказал, по умолчанию установлено в TextInputFormat.

Теперь предположим, что ваш входные данные кучу новой строки разделенных записей, разделенных запятой:

  • "А, value1"
  • "B, значение2"

Если вы хотите, чтобы ключ ввода к отображаемому устройству был («A», «value1»), («B», «value2»), вам придется реализовать пользовательский InputFormat и RecordReader с подписью <Text, Text>. К счастью, это довольно легко. Существует an example here и, вероятно, несколько примеров, плавающих вокруг StackOverflow.

Короче говоря, добавьте класс, который расширяет FileInputFormat<Text, Text> и класс, который распространяется на RecordReader<Text, Text>. Переопределите метод FileInputFormat#getRecordReader и верните экземпляр своего пользовательского RecordReader.

Затем вам нужно будет реализовать требуемую логику RecordReader. Самый простой способ сделать это - создать экземпляр LineRecordReader в своем пользовательском RecordReader и делегировать все основные обязанности этому экземпляру. В методах getCurrentKey и getCurrentValue вы реализуете логику для извлечения содержимого текста с разделителями-запятыми, вызывая LineRecordReader#getCurrentValue и разбивая его на запятую.

Наконец, установите новый InputFormat как Input InputFormat, как показано после второго абзаца выше.

+0

спасибо. Было приятно. Можете ли вы также рассказать мне, как вы об этом знаете? Любая важная ссылка, которую вы хотите поделиться? – Ronin

+0

Главным образом собирать эти биты информации шаг за шагом с помощью googling и т. Д. Тот же путь, на котором вы сейчас находитесь. :) Но чтение через части книги Hadoop: Полное руководство было очень полезно. Это дает довольно полное введение Hadoop. –

+1

использовать 'job.setInputFormatClass (MyTextInputFormat.class)' в новых пакетах Hadoop – pedromateo

1

В книге «Hadoop: The Difinitive Guide» Тома Уайт Я думаю, что у него есть соответствующий ответ на этот вопрос (стр.197):

« ключи TextInputFormat, будучи просто смещение в файле, как правило, не очень полезно Это является общим для каждой строки в файле, чтобы быть пару ключ-значение, разделенных разделителем таковой. как символ табуляции. Например, это выход производства TextOutputFormat, Hadoop по умолчанию OUTPUTFORMAT. Для того, чтобы интерпретировать эти файлы правильно, KeyValueTextInputFormat подходит.

Вы можете указать разделитель через key.value. separator.in.input.line свойство. I t является символом табуляции по умолчанию. "

+0

Спасибо! Я читаю эту книгу в первый раз, и я не мог понять, откуда начинался ключ LongWritable. Ваш комментарий здесь помог мне направить ответ, который мне нужен, и ваш ответ здесь пояснил это для меня. –

+0

Как я могу получить разделитель хеш-значений между ключом и значением в java Map уменьшить программу? –

-3

Ключ для ввода Mapper всегда будет целым типом .... клавиша ввода картографа указывает смещение линии нет. и значения указывают на всю строку ...... записывающее устройство считывает одну строку в первом цикле. И o/p картографа может быть любым, что захочет (может быть (текст, текст) или (текст, встроенный) или ......)

+0

Это длинный, а не Int –

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