温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

四、MapReduce中的排序

发布时间:2020-06-15 15:08:22 来源:网络 阅读:963 作者:隔壁小白 栏目:大数据

一、排序概述

1、在MapReduce的shuffle过程中执行了三次排序,分别是:
map的溢写阶段:根据分区以及key进行快速排序
map的合并溢写文件:将同一个分区的多个溢写文件进行归并排序,合成大的溢写文件
reduce输入阶段:将同一分区,来自不同map task的数据文件进行归并排序

2、在MapReduce整个过程中,默认是会对输出的KV对按照key进行排序的,而且是使用快速排序。
map输出的排序的,其实也就是上面的溢写过程中的排序。
reduce输出的排序,即reduce处理完数据后,MapReduce内部会自动对输出的KV按照key进行排序

以上排序都是根据KV中的Key进行排序的。所以当我们自定义的类作为Key时,需要实现WritableComparable 接口,也就是实现里面的 compareTo() 方法,用于排序时进行比较。
比较规则如下:

public int compareTo(object other) {
    this>other 返回1,正序,返回 -1,逆序。
}

二、二次排序的定义

而在依据key进行排序时,如果key是一个复合对象,即该对象中包含多个成员属性,那么在进行key比较时,就会涉及到多个属性间的比较,而如果compareTo() 方法中,比较条件为两个的话,就称为二次排序

三、辅助排序的定义

辅助排序也叫分组排序,是指在reduce前的group过程中根据排序规则进行的分组,因为分组的时候是需要比较KV中key是否相同,如果相同才会归为同一个组,如果不相等,就归为不同的组,所以就涉及到key比较方法了。总的来说其实定义key在什么情况下才相等。这个过程可以自己定义分组的方法,也就是分组排序的实现类。
使用方法:
1、自定义分组类,继承 WritableComparator
2、调用父类的构造方法,创建实例
3、重写父类的 compare方法

例子:

public class OrderGroupCompartor extends WritableComparator {

    protected OrderGroupCompartor() {
        super(OrderBean.class, true);
    }

    /**
     * 以orderbean对象中的ID为分组依据。
     * 同一ID的认为是同一个group,一个group只会调用一次reduce
     *
     * @param a  比较对象1
     * @param b  比较对象2
     * @return
     */
    @Override
    public int compare(WritableComparable a, WritableComparable b) {
        OrderBean aOrderBean = (OrderBean) a;
        OrderBean bOrderBean = (OrderBean) b;

        if (aOrderBean.getID() > bOrderBean.getID()) {
            return 1;
        } else if (aOrderBean.getID() < bOrderBean.getID()) {
            return -1;
        } else {
            return 0;
        }
    }
}

我们要注意的是,在进行分组时,同一个分组内的key是以第一个进入该分区的KV对中的key为准的。如:

有两个KV对:
1、<[1,裤子],20>
2、<[1,袜子],21>
其中key由id和物品名称组成的,value则是物品价格
假设分组依据是根据key中的id来分组的,那么上面两个KV是属于同一个group,但是实际上这两个KV
的key是不相等的。当1号KV先进入该group,那么就会以1号的key作为该group的key,分组的结果为:
<[1,裤子],[20,21]>
如果2号KV先进入,则按照前面的规则,分组结果为:
<[1,袜子],[20,21]>

就会有这样的情况的发生,我们要注意利用好这点。

那么谁先进入该group的呢?很简单,是按照事先排序的顺序,在前面的自然先进入。这里的排序其实就是前面reduce端的归并排序的结果,而使用的排序依据其实就是key的包装类中compareTo方法,属于普通排序里面的东西。

编写好自定义的分组排序类之后,需要在job中指定好自定义的分组类:

job.setGroupingComparatorClass(OrderGroupCompartor.class);

四、排序实例

普通排序请看 “MapReduce-统计手机号流量”
二次排序和辅助排序请看 “MapReduce--获取价格最高的商品”

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI