映射器在Hadoop中输入键值对

Ron*_*nin 12 hadoop mapreduce key-value

通常,我们以以下形式编写映射器:

public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable>
Run Code Online (Sandbox Code Playgroud)

这里映射器的输入键值对<LongWritable, Text>- 据我所知,当映射器获取输入数据时,它逐行通过 - 因此映射器的键表示行号 - 如果我错了请纠正我.

我的问题是:如果我给mapper的输入键值对 <Text, Text>那么就会给出错误

 java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text
Run Code Online (Sandbox Code Playgroud)

是否必须将mapper的输入键值对作为 <LongWritable, Text> - 如果是,那么为什么?如果没有那么错误的原因是什么?你能帮我理解错误的正确推理吗?

提前致谢.

Ale*_* A. 30

映射器的输入取决于使用的是什么InputFormat.InputFormat负责读取传入的数据并将其整形为Mapper期望的任何格式.默认的InputFormat是TextInputFormat,它扩展FileInputFormat<LongWritable, Text>.

如果不更改InputFormat,则使用具有不同Key-Value类型签名的Mapper <LongWritable, Text>将导致此错误.如果您希望<Text, Text>输入,则必须选择合适的InputFormat.您可以在作业设置中设置InputFormat:

job.setInputFormatClass(MyInputFormat.class);
Run Code Online (Sandbox Code Playgroud)

就像我说的,默认情况下,它设置为TextInputFormat.

现在,假设您的输入数据是一串由逗号分隔的换行符分隔的记录:

  • "A,值1"
  • "B,值2"

如果希望映射器的输入键为("A","value1"),("B","value2"),则必须使用<Text, Text>签名实现自定义的InputFormat和RecordReader .幸运的是,这很容易.这里有一个例子,可能还有几个浮动StackOverflow的例子.

简而言之,添加一个扩展FileInputFormat<Text, Text>的类和一个扩展的类RecordReader<Text, Text>.重写该FileInputFormat#getRecordReader方法,并让它返回自定义RecordReader的实例.

然后,您将必须实现所需的RecordReader逻辑.最简单的方法是在自定义RecordReader中创建LineRecordReader实例,并将所有基本职责委托给此实例.在getCurrentKey和getCurrentValue方法中,您将通过LineRecordReader#getCurrentValue在逗号上调用并拆分逗号来实现用于提取逗号分隔的Text内容的逻辑.

最后,将新的InputFormat设置为Job InputFormat,如上面第二段所示.