mapreduce 二次排序 Partitioner/SortComparator/GroupingComparator

翻了以前代码看了下15年时候写的二次排序 哈哈 怀念

 

实现hadoop自带WritableComparable 序列化排序接口

package com.lei.sort;

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

import org.apache.hadoop.io.WritableComparable;

public class StrWritable implements WritableComparable<StrWritable>{
    private  String strName;
    private  String strValue;
    public void setstrName(String strName) {
        this.strName = strName;
    }
    public void setstrValue(String strValue) {
        this.strValue = strValue;
    }
    public String getstrName() {
        return strName;
    }
    public String getstrValue() {
        return strValue;
    }
    @Override
    public void write(DataOutput out) throws IOException {
        out.writeUTF(strName);
        out.writeUTF(strValue);
    }
    @Override
    public void readFields(DataInput in) throws IOException {
        strName =in.readUTF();
        strValue =in.readUTF();
    }
    @Override
    public int compareTo(StrWritable o) {
        //这里只对StrName进行比较,在Job中在没有分组函数情况下,默认是这个排序,也可以重新定 义
        int  i= o.getstrName().compareTo(this.strName);
        //if(i!=0)
            return i;
        //return o.getstrName().compareTo(this.strName);

    }
}

 

Main函数

package com.lei.sort;

import java.io.IOException;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class JobStr {

    /**
     * @param args
     * @throws IOException 
     * @throws InterruptedException 
     * @throws ClassNotFoundException 
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        if(args.length!=2){
            System.err.println("输入正确的参数");
            System.exit(2);
        }

        Configuration conf = new  Configuration();

        Job job = Job.getInstance(conf,"JobStr Dino");
        job.setJarByClass(JobStr.class);

        job.setMapperClass(MapStr.class);
        job.setInputFormatClass(KeyValueTextInputFormat.class);


        job.setReducerClass(ReduceStr.class);
        job.setMapOutputKeyClass(StrWritable.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setSortComparatorClass(SortComparator.class);
        job.setGroupingComparatorClass(StrNameComparator.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        //判断输入路径是否存在,存在即删除
                FileSystem fs= FileSystem.get(URI.create(args[1]), conf,"root");
                Path path  = new Path(args[1]);
                if(fs.exists(path))
                {   try 
                    {
                        fs.delete(path, true);
                        System.out.println(path.getName() + "删除成功 ");
                    }catch(Exception e){
                        System.err.println(e.getMessage());
                    }
                }

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

 

map端:

package com.lei.sort;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class MapStr extends Mapper<Object, Text, StrWritable, IntWritable>{
    private StrWritable sw=new StrWritable();
    private IntWritable intWritable =new IntWritable(0);
    @Override
    protected void map(Object key, Text value,
            Context context)
            throws IOException, InterruptedException {
        // 这里用的inputformat输入格式为KeyValueTextInputFormat  所以会自动将key设置为第一列,第二列为value
        sw.setstrName(key.toString());
        sw.setstrValue(value.toString());
        int valueint=Integer.parseInt(value.toString());
        intWritable.set(valueint);
        context.write(sw, intWritable);
    }
}

 

reduce端:

package com.lei.sort;
import java.io.IOException;
import java.util.Iterator;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class ReduceStr  extends Reducer<StrWritable, IntWritable, Text, Text>{
    //static{System.out.println("-----------------------------------");}
    @Override
    protected void reduce(StrWritable sw, Iterable<IntWritable> iterable,
            Context context)
            throws IOException, InterruptedException {
        Iterator<IntWritable>  it =iterable.iterator();
        StringBuffer sb = new StringBuffer();
        while(it.hasNext()){
            sb.append(it.next().get()).append(',');
        }
        if(sb.length()>0)
            sb.deleteCharAt(sb.length()-1);
        System.out.println(sw.getstrName() +" ======= ========= "+sb.toString());
        context.write(new Text(sw.getstrValue()), new Text(sb.toString()));
    }
}

 

每个分区内又调用job.setSortComparatorClass()设置的key比较函数类排序(如果没有通过job.setSortComparatorClass()设置key比较函数类,则使用key的实现的compareTo方法)。可以看到,这是一个二次排序。

package com.lei.sort;

import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;

public class SortComparator extends  WritableComparator{
    public SortComparator(){
        super(StrWritable.class,true);
    }
    @Override
    @SuppressWarnings("rawtypes")
    public int compare(WritableComparable a,  WritableComparable b) {
        StrWritable s1 = (StrWritable)a;
        StrWritable s2 =(StrWritable)b;
        int i = s1.getstrName().compareTo(s2.getstrName());
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&");
        if(i!=0)
            return i;
        return s1.getstrValue().compareTo(s2.getstrValue());
    }
}

 

secondary sort阶段

然后开始构造一个key对应的value迭代器。这时就要用到分组,使用jobjob.setGroupingComparatorClass()设置的分组函数类。只要这个比较器比较的两个key相同,他们就属于同一个组,它们的value放在一个value迭代器,而这个迭代器的key使用属于同一个组的所有key的第一个key。

package com.lei.sort;

import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;

/*关于实现的是降序还是升序问题,进行比较看返回值,返回1为升序 -1位降序
 * */
public class StrNameComparator extends  WritableComparator{
    public StrNameComparator(){
        super(StrWritable.class,true);
    }
    @Override
    @SuppressWarnings("rawtypes")
    public int compare(WritableComparable a, WritableComparable b) {
        StrWritable s1 = (StrWritable)a;
        StrWritable s2 =(StrWritable)b;
        System.out.println("Map key " + s1.getstrName() +"######### "+s2.getstrName());
        return s1.getstrName().compareTo(s2.getstrName());
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MapReduce二次排序算法是一种基于分布式计算框架的排序算法,它通过将数据集拆分成多个小数据集,并通过多个节点进行并行计算,以提高算法的处理效率和精度。在学习和实践MapReduce二次排序算法的过程中,我有以下几点感悟: 首先,MapReduce二次排序算法的核心是将数据按照多个关键字进行排序。在实际应用中,往往需要按照多个关键字对数据进行排序,例如按照时间和地点对数据进行排序。通过MapReduce二次排序算法,可以很方便地对数据按照多个关键字进行排序,从而满足实际应用需求。 其次,MapReduce二次排序算法的实现需要考虑数据的分布和负载均衡问题。由于数据集被拆分成多个小数据集,数据的分布情况会影响到算法的处理效率和精度。因此,在实现MapReduce二次排序算法时,需要考虑数据的分布情况和负载均衡问题,以保证算法的效率和精度。 最后,MapReduce二次排序算法的应用场景非常广泛。例如,在电商网站中,可以通过对订单数据按照时间和金额进行排序,以分析用户的购买行为和消费习惯;在金融领域中,可以对交易数据按照时间和交易金额进行排序,以分析市场走势和风险等方面。 总之,MapReduce二次排序算法是一种非常有意义的排序算法,它可以帮助我们更好地理解大数据的排序问题,从而作出更加准确的决策。在学习和实践MapReduce二次排序算法的过程中,我们需要注重算法的理论和实践结合,以便更好地理解算法的核心思想和应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值