You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloudera MapReduce计数器getValue错误及任务后取值需求咨询

搞定仅Map MapReduce程序的计数器显示问题

我来帮你实现这个带计数器的仅Map任务,并且教你怎么在任务完成后拿到计数器的最终值——不管是在代码里打印,还是通过Cloudera的工具查看都没问题!

首先,先修正你的Mapper代码

先提个关键问题:final是Java的关键字,绝对不能用来当变量名,我给你改成finalStr了,顺便补全了逻辑:

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    // 定义咱们的自定义计数器枚举
    public static enum MY_COUNTER {
        C1, C2
    }

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // 把输入的Text转成字符串,避开final关键字
        String finalStr = value.toString().trim();
        
        // 匹配到Foo就递增C1,匹配到Bar就递增C2(你可以根据自己的需求改判断逻辑)
        if (finalStr.equals("Foo")) {
            context.getCounter(MY_COUNTER.C1).increment(1);
        } else if (finalStr.equals("Bar")) {
            context.getCounter(MY_COUNTER.C2).increment(1);
        }
        // 仅Map程序可以不用输出键值对,要是有输出需求的话再加对应的write逻辑就行
    }
}

然后,写仅Map任务的Driver程序

因为是仅Map任务,咱们要把Reducer的数量设为0,而且可以在任务跑完后直接通过Job对象获取计数器的值并打印出来:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class MyMapOnlyJobDriver {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "Map-Only Counter Job");
        
        job.setJarByClass(MyMapOnlyJobDriver.class);
        job.setMapperClass(MyMapper.class);
        
        // 核心:设置为仅Map任务,不需要Reducer
        job.setNumReduceTasks(0);
        
        // 声明输出类型(虽然仅Map任务可以不输出,但规范起见还是写上)
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        
        // 指定输入输出路径(运行时传参)
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        
        // 提交任务并等待完成
        boolean jobSuccess = job.waitForCompletion(true);
        
        // 任务成功完成后,获取并打印计数器值
        if (jobSuccess) {
            long c1Value = job.getCounters().findCounter(MyMapper.MY_COUNTER.C1).getValue();
            long c2Value = job.getCounters().findCounter(MyMapper.MY_COUNTER.C2).getValue();
            
            System.out.println("✅ 计数器C1最终值: " + c1Value);
            System.out.println("✅ 计数器C2最终值: " + c2Value);
        }
        
        System.exit(jobSuccess ? 0 : 1);
    }
}

除了代码打印,还有两种查看方式

1. 通过Cloudera Manager UI查看

  • 登录Cloudera Manager,找到YARN服务
  • 进入Applications页面,找到你的MapReduce任务
  • 点进任务详情,切换到Counters标签,就能看到咱们自定义的MY_COUNTER分类下的C1和C2数值了

2. 命令行查看

任务跑完后,在集群的命令行里用这两个命令(替换成你的任务ID):

# 查看C1的数值
mapred job -counter <你的任务ID> MyMapper$MY_COUNTER C1

# 查看C2的数值
mapred job -counter <你的任务ID> MyMapper$MY_COUNTER C2

这样不管你是想在程序里自动打印,还是事后通过工具查看,都能拿到计数器的最终值啦!

内容的提问来源于stack exchange,提问作者Aqsha Padyani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:21:04