大数据开发——Hadoop三大核心之Mapreduce基本原理与工作机制(三)

183 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」。

4. MapReduce 中的计数器

计数器是收集作业统计信息的有效手段之一,用于质量控制或应用级统计。计数器还可辅助诊断系统故障。如果需要将日志信息传输到 map 或 reduce 任务, 更好的方法通常是看能否用一个计数器值来记录某一特定事件的发生。对于大型分布式作业而言,使用计数器更为方便。除了因为获取计数器值比输出日志更方便,还有根据计数器值统计特定事件的发生次数要比分析一堆日志文件容易得多。

hadoop内置计数器列表

MapReduce任务计数器————org.apache.hadoop.mapreduce.TaskCounter

文件系统计数器————org.apache.hadoop.mapreduce.FileSystemCounter

FileInputFormat计数器————org.apache.hadoop.mapreduce.lib.input.FileInputFormatCounter

FileOutputFormat计数器————org.apache.hadoop.mapreduce.lib.output.FileOutputFormatCounter

作业计数器————org.apache.hadoop.mapreduce.JobCounter

第一种方式

第一种方式定义计数器,通过context上下文对象可以获取我们的计数器,进行记录 通过context上下文对象,在map端使用计数器进行统计

public class PartitionMapper  extends

Mapper<LongWritable,Text,Text,NullWritable>{

   //map方法将K1和V1转为K2和V2

   @Override

   protected void map(LongWritable key, Text value, Context context)

throws Exception{

       Counter counter = context.getCounter("MR_COUNT",

"MyRecordCounter");

       counter.increment(1L);

       context.write(value,NullWritable.get());

  }

}

运行程序之后就可以看到我们自定义的计数器在map阶段读取了七条数据

第二种方式

通过enum枚举类型来定义计数器 统计reduce端数据的输入的key有多少个

public class PartitionerReducer extends

Reducer<Text,NullWritable,Text,NullWritable> {

  public static enum Counter{

      MY_REDUCE_INPUT_RECORDS,MY_REDUCE_INPUT_BYTES

  }

   @Override

   protected void reduce(Text key, Iterable<NullWritable> values,

Context context) throws IOException, InterruptedException {

      context.getCounter(Counter.MY_REDUCE_INPUT_RECORDS).increment(1L);

      context.write(key, NullWritable.get());

  }

}

5. MapReduce 排序和序列化

  • 序列化 (Serialization) 是指把结构化对象转化为字节流

  • 反序列化 (Deserialization) 是序列化的逆过程. 把字节流转为结构化对象. 当要在进程间传递对象或持久化对象的时候, 就需要序列化对象成字节流, 反之当要将接收到或从磁盘读取的字节流转换为对象, 就要进行反序列化

  • Java 的序列化 (Serializable) 是一个重量级序列化框架, 一个对象被序列化后, 会附带很多额外的信息 (各种校验信息, header, 继承体系等), 不便于在网络中高效传输. 所以, Hadoop自己开发了一套序列化机制(Writable), 精简高效. 不用像 Java 对象类一样传输多层的父子关系, 需要哪个属性就传输哪个属性值, 大大的减少网络传输的开销

  • Writable 是 Hadoop 的序列化格式, Hadoop 定义了这样一个 Writable 接口. 一个类要支持可序列化只需实现这个接口即可

  • 另外 Writable 有一个子接口是 WritableComparable, WritableComparable 是既可实现序列化, 也可以对key进行比较, 我们这里可以通过自定义 Key 实现 WritableComparable 来实现我们的排序功能