繁体   English   中英

映射器在Hadoop中输入键值对

[英]Mapper input Key-Value pair in Hadoop

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

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

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

我的问题是:如果我将mapper的输入键值对赋予<Text, Text>则它会给出错误

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

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

提前致谢。

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

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

job.setInputFormatClass(MyInputFormat.class);

就像我说的,默认情况下,它设置为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,如上面第二段所示。

在汤姆怀特的“Hadoop:The Difinitive Guide”一书中,我认为他对此有适当的答案(第197页):

“TextInputFormat的键,只是文件中的偏移量,通常不是很有用。文件中的每一行通常都是一个键值对,由一个分隔符(如制表符)分隔。例如,这是TextOutputFormat产生的输出,Hadoop的默认OutputFormat。要正确解释这些文件,KeyValueTextInputFormat是合适的。

您可以通过key.value.separator.in.input.line属性指定分隔符。 默认情况下它是制表符。“

Mapper Input的键始终为Integer类型.... mapper输入键表示行的偏移号。 并且值表示整行......记录读取器在第一个循环中读取单行。 并且映射器的o / p可以是你想要的任何东西(它可以是(Text,Text)或(Text,IntWritable)或......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM