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
相关产品推荐
相关产品推荐

