-
之前,在展示MR作业的结果时,我们发现会有一些统计数据输出
21/04/06 09:51:19 INFO mapreduce.Job: Counters: 49 File System Counters FILE: Number of bytes read=67 FILE: Number of bytes written=416357 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=158 HDFS: Number of bytes written=20 HDFS: Number of read operations=6 HDFS: Number of large read operations=0 HDFS: Number of write operations=2
-
这些统计数据都来自MR的计数器
1. 计数器
1.1 计数器
- 考虑一个问题:如何统计map任务和reduce任务在文件系统中读写次数?
- 如果通过日志进行统计,map任务和reduce任务的日志在不同的文件,需要传输到某个节点进行汇总统计
- 如果,我们能使用计数变量分别统计每个任务的读写次数,然后再由Application Master进行汇总,则能避免日志文件的传输开销
- 因此,使用计数器统计MR作业或任务中特定事件的发生次数,要比分析一对日志文件更加方便。
1.2 MR中的计数器
- MR中的计数器如下,共五组:任务计数器、文件系统计数器、输入计数器、输出计数器和作业计数器
- 在MR中,所有的统计信息基于作业级别或任务级别的。
- 因此,上述计数器实际可以分成两大类:任务计数器和作业计数器
(1)任务计数器:MR任务计数器、文件系统任务计数器、FileInputFormat
任务计数器、FileOutputFormat
任务计数器
(2)作业计数器 - 每组计数器具体包含哪些计数器,可以查阅资料
1.3 作业计数器和任务计数器的关联
任务计数器
- 由关联任务进行维护,并定期发送给Application Master。
- 同时,任务向Application Master全量发送计数器的值,避免了由于消息丢失引发错误。
- 作业运行完成后,Application Master会对任务计数器的值进行汇总
- 虽然汇总数据更加完整可靠,但是中间的值也非常有利于我们观察任务状态,例如内存相关的计数器
作业计数器
- 作业计数器不会随任务运行而改变,有Application Master维护
- 注意: 不会随任务运行而改变,是指不会像任务计数器的值一样,随任务运行而发生变化。
- 作业计数器的值在任务开始或结束时,就已经确定了。例如map任务数(失败或成功的任务数)
2. 自定义用户计数器
2.1 枚举类与自定义计数器
-
Java枚举类的类名,对应计数器的组名;枚举类中的字段,对应计数器的名字
-
例如,以下是一个任务计数器的枚举类:
enum CLUSTER_TYPE{ KYLIN, DRUID, PRESTO; }
-
在map任务运行时,如果检测到集群类型为kylin,则计数器加1:
context.getCounter(CLUSTER_TYPE.KYLIN).increment(1);
2.2 动态计数器
- 该小节的内容,自己并未看懂
- 如有后续需要深入了解,再补充
2.3 如何获取计数器
- 有时,作业执行完成后,我们需要获取某些计数器的值,以判断作业运行是否满足要求
-
根据作业ID,从集群中获取一个作业对象
Cluster cluster = new Cluster(getConf()); Job job = cluster.getJob(JobID.forName(jobID))
-
判断作业运行是否完成
if(!job.isCompleted()) { System.out.error("job " + jobID + " is not completed\n"); }
-
获取所有的计数器
Counters counters = job.getCounters();
-
获取指定计数器的值
long value = counters.findCounter(Temparature.MISSING).getValue();
3. 其他
MR中的join
- 基于Map端的join,会将输入数据集划分成相同数量的分区,分区中记录按照连接键排序
- 也就是说,要求输入数据的分区数相同,且分区中键的排序顺序也相同
4. 总结
- 个人觉得这部分的知识,是非常少的
- 计数器
- MR计数器与日志相比的优势:减少数据传输、方便统计
- MR计数器的分组和分类:5组,两大类:作业计数器、任务计数器
- 用户自定义计数器:通过枚举类,如何更新计数器的值?
- 如何获取作业中的计数器:
getJob()
、getCounters()
、findCounter()