hadoop3.x MapReduce-二次排序

说明

按照 hadoop3.x MapReduce-排序 执行后,输出结果如下:

充电站id    充电站id,充电次数,充电量,充电时间
2    2,4,1700,375
3    3,4,850,86
1    1,5,650,84
6    6,1,150,20
5    5,1,150,12
4    4,2,150,13

当 充电量相同 时,想 按照 充电时间 从小到大 正序 排列,就需要 修改 Cdz 类,让其支持 二次排序

关于 二次排序,详见:java Comparable 排序和二次排序

实现过程

统计和二次排序无法在一次 MapReduce 中完成

所以 先执行 hadoop3.x MapReduce序列化案例-统计充电桩充电量、充电时长、充电次数,结果如下:

1    1,5,650,84
2    2,4,1700,375
3    3,4,850,86
4    4,2,150,13
5    5,1,150,12
6    6,1,150,20

然后再实现一个 MapReduce ,读取上面的 结果文件,然后排序输出

java 代码

在 hadoop3.x MapReduce-排序 基础上,只修改 Cdz 类

充电站类

package sort2;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.WritableComparable;

public class Cdz implements WritableComparable<Cdz> {

    //充电桩编号
    private String id;
    //充电次数
    private int num;
    //用电量
    private int eleNum;
    //充电时长,单位:分钟
    private int time;

    //序列化
    @Override
    public void write(DataOutput out) throws IOException {
        //写的顺序与读的顺序相同,否则读写错乱
        out.writeUTF(id);
        out.writeInt(num);
        out.writeInt(eleNum);
        out.writeInt(time);
    }

    //反序列化
    @Override
    public void readFields(DataInput in) throws IOException {
        //写的顺序与读的顺序必须相同,否则读写错乱
        id=in.readUTF();
        num=in.readInt();
        eleNum=in.readInt();
        time=in.readInt();
    }

    //保存文件的格式
    @Override
    public String toString() {

        return id+","+num+","+eleNum+","+time;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    public int getEleNum() {
        return eleNum;
    }

    public void setEleNum(int eleNum) {
        this.eleNum = eleNum;
    }

    @Override
    public int compareTo(Cdz o) {
        int res=0;
        //如果当前对象的电量 > 另一个对象的电量,那么当前对象就排在前面,返回1
        if(this.eleNum > o.eleNum){
            res = -1;
        }else if(this.eleNum < o.eleNum){
            res = 1;
        }else{
            //当充电量相同时,根据充电时间排序,小的排在前面
            if(this.getTime()<o.getTime()){
                return -1;
            }else if(this.getTime() > o.getTime()){
                return 1;
            }else{
                return 0;
            }
        }
        return res;
    }

}

yarn执行

执行命令

hadoop jar /program/myjar/chongdianzhuang-0.0.1-SNAPSHOT.jar  sort.Main2  /chongdianzhan/res_first /chongdianzhan/res_sort2

注意: 参数 /chongdianzhan/res_first 是上一次 MapReduce 的输出结果

执行结果如下:

2    2,4,1700,375
3    3,4,850,86
1    1,5,650,84
5    5,1,150,12
4    4,2,150,13
6    6,1,150,20

原文出处:/show_1IX2DlNW0a6k.html