hadoop + Интерфейс с возможностью записи + readFields выдает исключение в редукторе - PullRequest
0 голосов
/ 19 сентября 2010

У меня есть простая программа сокращения карт, в которой моя карта и примитивы сокращения выглядят так:

map (K, V) = (Text, OutputAggregator)
Reduce (Text, OutputAggregator) = (Текст, Текст)

Важным моментом является то, что из моей функции карты я создаю объект типа OutputAggregator, который является моим собственным классом, реализующим интерфейс Writable. Тем не менее, мое снижение не удается со следующим исключением. Более конкретно, функция readFieds () выдает исключение. Любая подсказка, почему? Я использую hadoop 0.18.3

10/09/19 04:04:59 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId=
10/09/19 04:04:59 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same.
10/09/19 04:04:59 INFO mapred.FileInputFormat: Total input paths to process : 1
10/09/19 04:04:59 INFO mapred.FileInputFormat: Total input paths to process : 1
10/09/19 04:04:59 INFO mapred.FileInputFormat: Total input paths to process : 1
10/09/19 04:04:59 INFO mapred.FileInputFormat: Total input paths to process : 1
10/09/19 04:04:59 INFO mapred.JobClient: Running job: job_local_0001
10/09/19 04:04:59 INFO mapred.MapTask: numReduceTasks: 1
10/09/19 04:04:59 INFO mapred.MapTask: io.sort.mb = 100
10/09/19 04:04:59 INFO mapred.MapTask: data buffer = 79691776/99614720
10/09/19 04:04:59 INFO mapred.MapTask: record buffer = 262144/327680
Length = 10
10
10/09/19 04:04:59 INFO mapred.MapTask: Starting flush of map output
10/09/19 04:04:59 INFO mapred.MapTask: bufstart = 0; bufend = 231; bufvoid = 99614720
10/09/19 04:04:59 INFO mapred.MapTask: kvstart = 0; kvend = 10; length = 327680
gl_books
10/09/19 04:04:59 WARN mapred.LocalJobRunner: job_local_0001
java.lang.NullPointerException
 at org.myorg.OutputAggregator.readFields(OutputAggregator.java:46)
 at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:67)
 at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:40)
 at org.apache.hadoop.mapred.Task$ValuesIterator.readNextValue(Task.java:751)
 at org.apache.hadoop.mapred.Task$ValuesIterator.next(Task.java:691)
 at org.apache.hadoop.mapred.Task$CombineValuesIterator.next(Task.java:770)
 at org.myorg.xxxParallelizer$Reduce.reduce(xxxParallelizer.java:117)
 at org.myorg.xxxParallelizer$Reduce.reduce(xxxParallelizer.java:1)
 at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.combineAndSpill(MapTask.java:904)
 at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:785)
 at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:698)
 at org.apache.hadoop.mapred.MapTask.run(MapTask.java:228)
 at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:157)
java.io.IOException: Job failed!
 at org.apache.hadoop.mapred.JobClient.runJob(JobClient.java:1113)
 at org.myorg.xxxParallelizer.main(xxxParallelizer.java:145)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.apache.hadoop.util.RunJar.main(RunJar.java:155)
 at org.apache.hadoop.mapred.JobShell.run(JobShell.java:54)
 at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
 at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:79)
 at org.apache.hadoop.mapred.JobShell.main(JobShell.java:68)

Ответы [ 2 ]

3 голосов
/ 21 сентября 2010

При публикации вопроса о пользовательском коде: Разместите соответствующий фрагмент кода. Таким образом, содержание строки 46 и нескольких строк до и после действительно помогло бы ...:)

Однако это может помочь:

Подводный камень при написании собственного записываемого класса заключается в том, что Hadoop многократно использует фактический экземпляр класса. Между вызовами readFields вы НЕ получаете блестящий новый экземпляр.

Таким образом, в начале метода readFields вы ДОЛЖНЫ предположить, что объект, в котором вы находитесь, заполнен "мусором" и должен быть очищен перед продолжением.

Я предлагаю вам реализовать метод "clear ()", который полностью стирает текущий экземпляр и сбрасывает его в состояние, в котором он будет в момент после его создания и завершения конструктора. И, конечно, вы вызываете этот метод как первое, что есть в ваших readFields для ключа и значения.

НТН

1 голос
/ 17 октября 2013

В дополнение к ответу Niels Basjes: просто инициализируйте переменные-члены в пустом конструкторе (который вы должны предоставить, иначе Hadoop не сможет инициализировать ваш объект), например:

public OutputAggregator() {
    this.member = new IntWritable();
    ...
}

, предполагая, что this.member имеет тип IntWritable.

...