为啥 Mapper 类中没有使用 LongWritable(key)?

Posted

技术标签:

【中文标题】为啥 Mapper 类中没有使用 LongWritable(key)?【英文标题】:Why LongWritable (key) has not been used in Mapper class?为什么 Mapper 类中没有使用 LongWritable(key)? 【发布时间】:2015-12-15 12:47:46 【问题描述】:

映射器:

Mapper类是一个泛型类型,有四个形式类型参数,分别指定map函数的输入键、输入值、输出键和输出值类型

public class MaxTemperatureMapper
    extends Mapper<LongWritable, Text, Text, IntWritable> 
        private static final int MISSING = 9999;
        @Override
        public void map(LongWritable key, Text value, Context context)
          throws IOException, InterruptedException 
            String line = value.toString();
            String year = line.substring(15, 19);
            int airTemperature;
            if (line.charAt(87) == '+')  // parseInt doesn't like leading plus signs
                airTemperature = Integer.parseInt(line.substring(88, 92));
             else 
                airTemperature = Integer.parseInt(line.substring(87, 92));
        
        String quality = line.substring(92, 93);
        if (airTemperature != MISSING && quality.matches("[01459]")) 
            context.write(new Text(year), new IntWritable(airTemperature));
        
    

减速机:

四个形式类型参数用于指定输入和输出类型,这 减少功能的时间。 reduce函数的输入类型必须匹配map函数的输出类型:Text和IntWritable

public class MaxTemperatureReducer
extends Reducer<Text, IntWritable, Text, IntWritable> 
@Override
    public void reduce(Text key, Iterable<IntWritable> values, Context context)
    throws IOException, InterruptedException 
        int maxValue = Integer.MIN_VALUE;
        for (IntWritable value : values) 
            maxValue = Math.max(maxValue, value.get());
        
    context.write(key, new IntWritable(maxValue));
    

但在此示例中,从未使用过密钥。

Mapper中的key有什么用,完全没用过?

为什么 key 是 LongWritable 的?

【问题讨论】:

【参考方案1】:

本示例中使用的输入格式为TextInputFormat,它生成的键/值对为LongWritable/Text

这里的键LongWritable 表示从给定输入文件的Input Split 读取的当前行的偏移位置。其中Text 代表实际的当前行本身。

我们不能说LongWritable 键为文件中的每一行给出的行偏移值是没有用的。这取决于用例,根据您的情况,此输入键并不重要。

除了TextInputFormat,我们还有许多类型的InputFormat 类型,它们以不同的方式解析输入文件中的行并生成其相关的键/值对。

例如 KeyValueTextInputFormat 是 TextInputFormat 的子类,它使用配置 delimiter 解析每一行,并将键/值生成为 Text/Text

编辑:- 在下面找到一些输入格式和键/值类型的列表,

KeyValueTextInputFormat  Text/Text

NLineInputFormat         LongWritable/Text

FixedLengthInputFormat   LongWritable/BytesWritable

除了我们很少有输入格式在声明时采用基于泛型的自定义键/值类型。比如SequenceFileInputFormat, CombineFileInputFormat。请查看 Hadoop 权威指南中的输入格式章节。

希望这会有所帮助。

【讨论】:

你能提供一些例子,它有不同于 LongWritable 的键吗? 如果你想使用 combinefileinputformat 比你显然会使用一个文件名和偏移量作为你的键(跟踪你从哪个文件读取值),所以这取决于你创建你的自己的输入格式,如果你发现除了正常的偏移量之外还有一些有用的键,那么你可以使用它。【参考方案2】:

JobConf 类返回 LongWritable 作为默认类,如果你没有设置

job.setMapOutputValueClass(...)

JobConf代码中:-

public Class<?> getOutputKeyClass() 
    return getClass(JobContext.OUTPUT_KEY_CLASS,
                    LongWritable.class, Object.class);

【讨论】:

以上是关于为啥 Mapper 类中没有使用 LongWritable(key)?的主要内容,如果未能解决你的问题,请参考以下文章

Spring整合Mybatis遇到的问题

Hadoop之MapReduce学习之ip去重MaxScore示例TotalScoreMapper示例

为啥在我的自定义 UIView 类中没有调用 init(frame: CGRect)?

无法在 Spring Boot 的组件类中自动装配推土机 Mapper

是否有原因为啥仅存在于给定类中的特征没有被强烈预测到该类中?

在 Mapper 类中执行 Reducer 操作