36 MAPREDUCE自定义GroupingComparator

简介: 36 MAPREDUCE自定义GroupingComparator
需求

有如下订单数据:

现在需要求出每一个订单中成交金额最大的一笔交易。

分析

1、利用“订单id和成交金额”作为key,可以将map阶段读取到的所有订单数据按照id分区,按照金额排序,发送到reduce。

2、在reduce端利用groupingcomparator将订单id相同的kv聚合成组,然后取第一个即是最大值。

实现

自定义groupingcomparator

/**
 * 用于控制shuffle过程中reduce端对kv对的聚合逻辑
 * @author duanhaitao@itcast.cn
 *
 */
public class ItemidGroupingComparator extends WritableComparator {
  protected ItemidGroupingComparator() {
    super(OrderBean.class, true);
  }
  @Override
  public int compare(WritableComparable a, WritableComparable b) {
    OrderBean abean = (OrderBean) a;
    OrderBean bbean = (OrderBean) b;
    //将item_id相同的bean都视为相同,从而聚合为一组
    return abean.getItemid().compareTo(bbean.getItemid());
  }
}

定义订单信息bean

/**
 * 订单信息bean,实现hadoop的序列化机制
 * @author duanhaitao@itcast.cn
 *
 */
public class OrderBean implements WritableComparable<OrderBean>{
  private Text itemid;
  private DoubleWritable amount;
  public OrderBean() {
  }
  public OrderBean(Text itemid, DoubleWritable amount) {
    set(itemid, amount);
  }
  public void set(Text itemid, DoubleWritable amount) {
    this.itemid = itemid;
    this.amount = amount;
  }
  public Text getItemid() {
    return itemid;
  }
  public DoubleWritable getAmount() {
    return amount;
  }
  @Override
  public int compareTo(OrderBean o) {
    int cmp = this.itemid.compareTo(o.getItemid());
    if (cmp == 0) {
      cmp = -this.amount.compareTo(o.getAmount());
    }
    return cmp;
  }
  @Override
  public void write(DataOutput out) throws IOException {
    out.writeUTF(itemid.toString());
    out.writeDouble(amount.get());
  }
  @Override
  public void readFields(DataInput in) throws IOException {
    String readUTF = in.readUTF();
    double readDouble = in.readDouble();
    this.itemid = new Text(readUTF);
    this.amount= new DoubleWritable(readDouble);
  }
  @Override
  public String toString() {
    return itemid.toString() + "\t" + amount.get();
  }
}

编写mapreduce处理流程

/**
 * 利用secondarysort机制输出每种item订单金额最大的记录
 * @author duanhaitao@itcast.cn
 *
 */
public class SecondarySort {
  static class SecondarySortMapper extends Mapper<LongWritable, Text, OrderBean, NullWritable>{
    OrderBean bean = new OrderBean();
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
      String line = value.toString();
      String[] fields = StringUtils.split(line, "\t");
      bean.set(new Text(fields[0]), new DoubleWritable(Double.parseDouble(fields[1])));
      context.write(bean, NullWritable.get());
    }
  }
  static class SecondarySortReducer extends Reducer<OrderBean, NullWritable, OrderBean, NullWritable>{
    //在设置了groupingcomparator以后,这里收到的kv数据 就是:  <1001 87.6>,null  <1001 76.5>,null  .... 
    //此时,reduce方法中的参数key就是上述kv组中的第一个kv的key:<1001 87.6>
    //要输出同一个item的所有订单中最大金额的那一个,就只要输出这个key
    @Override
    protected void reduce(OrderBean key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
      context.write(key, NullWritable.get());
    }
  }
  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf);
    job.setJarByClass(SecondarySort.class);
    job.setMapperClass(SecondarySortMapper.class);
    job.setReducerClass(SecondarySortReducer.class);
    job.setOutputKeyClass(OrderBean.class);
    job.setOutputValueClass(NullWritable.class);
    FileInputFormat.setInputPaths(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    //指定shuffle所使用的GroupingComparator类
    job.setGroupingComparatorClass(ItemidGroupingComparator.class);
    //指定shuffle所使用的partitioner类
    job.setPartitionerClass(ItemIdPartitioner.class);
    job.setNumReduceTasks(3);
    job.waitForCompletion(true);
  }
}


目录
相关文章
|
分布式计算 Hadoop Java
MapReduce编程:自定义分区和自定义计数器
MapReduce编程:自定义分区和自定义计数器
189 0
|
分布式计算 数据库
35 MAPREDUCE自定义outputFormat
35 MAPREDUCE自定义outputFormat
100 0
|
5月前
|
分布式计算 Java 大数据
MapReduce自定义分组比较器(GroupingComparator)
总的来看,自定义的GroupingComparator为用户在MapReduce框架中实现特定的业务需求,提供了极大的便利和灵活性。只需要遵循上述步骤,即可轻松创建并使用自定义分组比较器。
101 22
|
存储 分布式计算 Hadoop
MapReduce编程模型——自定义序列化类实现多指标统计
MapReduce编程模型——自定义序列化类实现多指标统计
124 0
|
存储 分布式计算 关系型数据库
MapReduce【自定义OutputFormat】
MapReduce【自定义OutputFormat】
|
分布式计算
MapReduce【自定义InputFormat】
MapReduce【自定义InputFormat】
|
分布式计算
MapReduce【自定义分区Partitioner】
MapReduce【自定义分区Partitioner】
|
数据采集 分布式计算
34 MAPREDUCE自定义inputFormat
34 MAPREDUCE自定义inputFormat
88 0
|
11月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
254 3
|
分布式计算 Hadoop Java
Hadoop MapReduce编程
该教程指导编写Hadoop MapReduce程序处理天气数据。任务包括计算每个城市ID的最高、最低气温、气温出现次数和平均气温。在读取数据时需忽略表头,且数据应为整数。教程中提供了环境变量设置、Java编译、jar包创建及MapReduce执行的步骤说明,但假设读者已具备基础操作技能。此外,还提到一个扩展练习,通过分区功能将具有相同尾数的数字分组到不同文件。
142 1

热门文章

最新文章