通常,我们以以下形式编写Map器:
public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable>
这里Map器的输入键值对是 <LongWritable, Text>
-据我所知,当Map器获得输入数据时,它会逐行通过-因此Map器的键表示行号-如果我错了,请纠正我。
我的问题是:如果我给mapper的输入键值对 <Text, Text>
然后它给出了错误
java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text
是否必须将Map器的输入键值对指定为 <LongWritable, Text>
-如果是,为什么?如果没有,那么错误的原因是什么?你能帮我理解错误的正确原因吗?
提前谢谢。
3条答案
按热度按时间h9a6wy2h1#
Map器输入的键将始终是整数类型….Map器输入键表示该行的偏移号,值表示整行。。。。。。记录读取器在第一个循环中读取一行。Map器的o/p可以是您想要的任何内容(可以是(text,text)或(text,intwritable)或……)
ppcbkaq52#
Map器的输入取决于所使用的inputformat。inputformat负责读取传入的数据并将其格式化为Map程序所期望的格式
FileInputFormat<LongWritable, Text>
.如果不更改输入格式,请使用与签名具有不同键值类型的Map器
<LongWritable, Text>
将导致此错误。如果你期待的话<Text, Text>
输入时,必须选择合适的输入格式。您可以在作业设置中设置输入格式:就像我说的,默认设置为textinputformat。
现在,假设您的输入数据是一组以逗号分隔的换行记录:
“a,值1”
b,值2
如果希望Map器的输入键为(“a”,“value1”),(“b”,“value2”),则必须使用
<Text, Text>
签名。幸运的是,这很容易。这里有一个例子,也可能有一些例子围绕stackoverflow浮动。简而言之,添加一个扩展
FileInputFormat<Text, Text>
以及一个RecordReader<Text, Text>
. 覆盖FileInputFormat#getRecordReader
方法,并让它返回自定义recordreader的示例。然后必须实现所需的recordreader逻辑。最简单的方法是在自定义recordreader中创建一个linerecordreader示例,并将所有基本职责委派给该示例。在getcurrentkey和getcurrentvalue方法中,您将实现通过调用
LineRecordReader#getCurrentValue
用逗号分开。最后,将新的inputformat设置为job inputformat,如上面第二段后面所示。
xpcnnkqh3#
在汤姆·怀特的《hadoop:定义指南》一书中,我认为他对此有一个恰当的答案(第197页):
textinputformat的键只是文件中的偏移量,通常不是很有用。文件中的每一行通常是一个键值对,由分隔符(如制表符)分隔。例如,这是由textoutputformat(hadoop的默认outputformat)生成的输出。要正确解释这些文件,keyvaluetextinputformat是合适的。
可以通过key.value.separator.in.input.line属性指定分隔符。默认为制表符。“