mapreduce 二次排序

Mapreduce二次排序实例 Mapreduce可以简单的分为三个阶段:map阶段、shuffle阶段、reduce阶段。shuffle阶段包括分区、分组两个步骤,二次排序发生在分区步骤。 分区:通过分区函数将满足条件的分在同一个区(第一次排序)。同一个区的数据然后再排序(第二次排序)。分区是对key进行操作。 分组:将相同key值的value整合成一个集合() 实例:有一张phone表,包含mac、time 阅读详情

目标: 

 

输入数据:

  1. sort1   1  
  2. sort2   3  
  3. sort2   88  
  4. sort2   54  
  5. sort1   2  
  6. sort6   22  
  7. sort6   888  
  8. sort6   58

 

 

 

       输出数据:

 

  1. sort1   1,2  
  2. sort2   3,54,88  
  3. sort6   22,58,888  

既然是二次排序,所以上述的输入数据必须在同一分区中,不然达不到我们想要的二次排序效果。MapReduce框架默认是对key进行排序的,这里我们需要自定义排序方法对key进行排序。

 

先理解MapReduce处理数据的流程:

(这是在另一个大神的博客看到的     http://blog.youkuaiyun.com/lzm1340458776/article/details/42875751)

 

我们应该先深刻的理解MapReduce处理数据的整个流程,这是最基础的,不然的话是不可能找到解决问题的思路的。我描述一下MapReduce处理数据的大概流程:首先,MapReduce框架通过getSplits()方法实现对原始文件的切片之后,每一个切片对应着一个MapTask,InputSplit输入到map()函数进行处理,中间结果经过环形缓冲区的排序,然后分区、自定义二次排序(如果有的话)和合并,再通过Shuffle操作将数据传输到reduce Task端,reduce端也存在着缓冲区,数据也会在缓冲区和磁盘中进行合并排序等操作,然后对数据按照key值进行分组,然后每处理完一个分组之后就会去调用一次reduce()函数,最终输出结果。大概流程 我画了一下,如下图:

大概解决思路:

map端排序:

首先将输入数据放到同一分区中并对其进行排序,因为MapReduce排序只对key进行排序,所以我们需要一个组合key,以[key,value]的形式输入,map输入的数据类型结构大概为{[key,value],value}:

 

  1. {[sort1,1],1}  
  2. {[sort2,3],3}  
  3. {[sort2,88],88}  
  4. {[sort2,54],54}  
  5. {[sort1,2],2}  
  6. {[sort6,22],22}  
  7. {[sort6,888],888}  
  8. {[sort6,58],58}  

温馨提示:请务必保证map端排序结果正确,不然不管怎么分组都得不到你想要的结果(本人就踩过这坑,费了好长时间才找到原因)。

 

map端排序后的结果应该如下:

 

  1. sort1:1,
    sort1:2,
    sort2:3,
    sort2:54,
    sort2:88,
    sort6:22,
    sort6:58,
    sort6:888,
  2.   

reduce端分组:

 

前面提到过,reduce方法执行的次数是由分组数决定的。在reduce端按组合key的第一个字段进行分组,然后再对对应的value值进行相应的处理则可以达到我们想要的结果。

 

  1. sort1   1,2  
  2. sort2   3,54,88  
  3. sort6   22,58,888  

 

 

 

 

具体的代码实现如下:

自定义排序类:

 

package com.secondSortJob;

import com.sun.deploy.util.ArrayUtil;
import org.apache.commons.lang.ArrayUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;

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


/**
 * Created by Administrator on 2018/1/28 0028.
 */
public class SecondKeySort implements WritableComparable<SecondKeySort> {
    private Text key = new Text();
    private IntWritable count = new IntWritable();

    public SecondKeySort(Text key, IntWritable count) {
        this.key = key;
        this.count = count;
    }

    public SecondKeySort() {
    }

    public Text getKey() {

        return key;
    }

    public void setKey(Text key) {
        this.key = key;
    }

    public IntWritable getCount() {
        return count;
    }

    public void setCount(IntWritable count) {
        this.count = count;
    }

    public void write(DataOutput dataOutput) throws IOException {
//        new Text("["+this.key.toString()+","+this.count.toString()+"]");
        this.key.write(dataOutput);
        this.count.write(dataOutput);
    }

    public void readFields(DataInput dataInput) throws IOException {
        this.key.readFields(dataInput);
        this.count.readFields(dataInput);
    }

    public int compareTo(SecondKeySort o) {
        String keyStr1 = this.key.toString().substring(0,this.key.toString().length());
        String keyStr2 = o.getKey().toString().substring(0,o.getKey().toString().length());

        String[] keyStr1Arr = keyStr1.split("\t");
        String[] keyStr2Arr = keyStr2.split("\t");

        String keyStr1Text = keyStr1Arr [0];
        String keyStr2Text = keyStr2Arr [0];

        if(!keyStr1Text.equals(keyStr2Text)){
            System.out.println(keyStr1Text.compareTo(keyStr2Text));
            return keyStr1Text.compareTo(keyStr2Text) ;
        }else{
            return  Integer.parseInt(this.count.toString()) - Integer.parseInt(o.getCount().toString()) ;
        }
    }

    @Override
    public String toString() {
        return  this.key.toString() +"\t" +this.count.toString();
    }

}

mapper任务类:

 

 

package com.secondSortJob;

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

import java.io.IOException;

/**
 * Created by Administrator on 2018/1/28 0028.
 */
public class SecondSortMapper extends Mapper<LongWritable ,Text,SecondKeySort,IntWritable> {
    private SecondKeySort secondKeySort = new SecondKeySort();
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] arrs = value.toString().split("\t");
        secondKeySort.setKey(new Text(arrs[0]));
        secondKeySort.setCount(new IntWritable(Integer.parseInt(arrs[1].trim())));
        context.write(secondKeySort,new IntWritable(Integer.parseInt(arrs[1].trim())));
        System.out.println(secondKeySort.toString()+"  "+arrs[1]);
    }
}

 

reduce任务类:

package com.secondSortJob;

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

import java.io.IOException;


/**
 * Created by Administrator on 2018/1/28 0028.
 */
public class SecondSortReducer extends Reducer<SecondKeySort,IntWritable,Text,NullWritable> {
    @Override
    protected void reduce(SecondKeySort key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        System.out.println("reduce action");
        String str = key.getKey().toString() +":";
        while (values.iterator().hasNext()){

            str = str + values.iterator().next()+",";
        }
        context.write(new Text(str),NullWritable.get());
    }
}

自定义分区类:(保证输入数据在同一个分区,分区数和Reduce任务数相等)

 

 

package com.secondSortJob;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.Partitioner;


/**
 * Created by Administrator on 2018/1/29 0029.
 */
public class GroupingPartitioner extends Partitioner<SecondKeySort,IntWritable> {
    public int getPartition(SecondKeySort secondKeySort, IntWritable intWritable, int i) {
        return secondKeySort.getKey().toString().hashCode()%i ;
    }
}

 

分组函数类:(可以实现RawComparator接口,也可以继承WritableComparator类)

 

package com.secondSortJob;

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

/**
 * Created by Administrator on 2018/1/28 0028.
 */
public class GroupingComparator implements RawComparator<SecondKeySort> {
    public int compare(byte[] bytes, int i, int i1, byte[] bytes1, int i2, int i3) {
        int compareBytes = WritableComparator.compareBytes(bytes, i, 8, bytes1, i2, 8);
        return compareBytes;
    }
    public int compare(SecondKeySort o1, SecondKeySort o2) {
        return o1.getKey().compareTo(o2.getKey());
    }
}

 

 

 

 

 

主程序加载类:

 

package com.secondSortJob;

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.LongWritable;
import org.apache.hadoop.io.NullWritable;
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.output.FileOutputFormat;

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

/**
 * 二次排序
 * Created by Administrator on 2018/1/28 0028.
 */
public class SecondSortJob {
    private  static     Configuration configuration = new Configuration();
    private  static     String master = "hdfs://192.168.8.222";
    private  static      String masterFS = "hdfs://192.168.8.222:9000";
    private    static      FileSystem fs = null ;

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        configuration.set("yarn.resourcemanager.hostname",master);
        fs =  FileSystem.get(URI.create(masterFS),configuration);
        Job job = Job.getInstance(configuration);

        String inputPath = "/lsw/secondSort.txt";
        String secondSortResult = "/lsw/secondSortResult" ;


        if(fs.isDirectory(new Path(masterFS+secondSortResult)))
            fs.delete(new Path(masterFS+secondSortResult));

        job.setMapOutputKeyClass(SecondKeySort.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);

        job.setJarByClass(SecondSortJob.class);
        job.setMapperClass(SecondSortMapper.class);
        job.setReducerClass(SecondSortReducer.class);

        job.setPartitionerClass(GroupingPartitioner.class);
        job.setGroupingComparatorClass(GroupingComparator.class);
//        job.setNumReduceTasks(3);
        FileInputFormat.addInputPath(job,new Path(masterFS+inputPath));
        FileOutputFormat.setOutputPath(job,new Path(masterFS+secondSortResult));

        job.waitForCompletion(true);
    }
}

 

 

 

MapReduce-三次排序-曾经想不通的二次排序 上一篇博客说明了怎么自定义Key,而且用了二次排序的例子来做测试,但没有详细的说明二次排序,这一篇说详细的说明二次排序, 为了说明曾经一个思想的误区,特地做了一个3个字段的二次排序来说明。后面称其为“三次排序”。 测试数据: a1,b2,c5 a4,b1,c3 a1,b2,c4 a2,b2,c4 a2,b1,c4 a4,b1,c2 测试目的:输出以下结果首先根据第一个自段排序,如 阅读详情

相关推荐

hadoop学习笔记(五)MapReduce常见实例二:排序(一次排序、二次排序、倒排索引)

目录 一次排序 MapReduce的默认排序规则 Map、Reduce任务中Shuffle和排序的过程 流程分析 任务描述 代码 执行结果 二次排序  任务描述 过程分析 代码 执行结果 倒排索引  任务描述 设计思路 代码 执行过程 执行结果   一次排序 熟悉MapReduce的人都知道,排序是MapReduce的天然特性!在数据达到reducer之前...

Lee的学习笔记 1万+

mapreduce二次排序详解

mapreduce二次排序详解 - linzch3 - 博客园 什么是二次排序 待排序的数据具有多个字段,首先对第一个字段排序,再对第一字段相同的行按照第二字段排序,第二次排序不破坏第一次排序的结果,这个过程就称为二次排序。 如何在mapreduce中实现二次排序 mapreduce的工作原理 MR的工作原理如下图(如果看不清可右键新标签页查看): 图片部分数据参考自:Hadoop — MapReduce原理解析 相关重点: 分区(partitioning):使得具有相同Key值的键值.

hellojoy的博客 2742

Solidworks曲面建模学习(三)——样条曲线

本文主要演示平面的空间样条曲线的一些绘制。

东东不熬夜的博客 6503

MapReduce的二次排序

MapReduce的二次排序 二次排序的需求说明    在mapreduce操作时,shuffle阶段会多次根据key值排序。但是在shuffle分组后,相同key值的values序列的顺序是不确定的(如下图)。如果想要此时value值也是排序好的,这种需求就是二次排序。                                      ...

雪泪寒的博客 2327

科研党必备:5分钟搞定Arxiv论文批量导入NoteExpress(附PDF自动下载技巧)

本文为科研人员提供了一套高效的自动化工作流,实现从Arxiv批量检索论文、自动下载PDF到无缝导入NoteExpress的全过程。通过Python脚本和NASA ADS等工具,可大幅提升文献管理效率,特别适合需要追踪前沿动态的研究生和科研团队。

orange的博客 398

Labelme AI-Polygon闪退排查与修复指南

本文详细介绍了Labelme AI-Polygon功能闪退问题的排查与修复方法,包括环境配置检查、模型路径设置、依赖库版本控制等关键步骤。通过系统性的解决方案和实用技巧,帮助用户快速解决闪退问题,确保数据标注工作的高效进行。

weixin_29311017的博客 140

MapReduce实现二次排序

默认情况下,Map输出的结果会按照key进行排序,但在实际的应用中,有时间我们不仅要对key进行排序,同时还要对value进行排序,这时候就要用到mapreduce中的二次排序。 一、 二次排序原理分析 我们对二次排序分为以下几个阶段: (1)Map起始阶段 在Map阶段,通过job.setInputFormatClass()定义的InputFormat,将输入的数据集切分成小的split,同时InputFormat提供一个RecordRead...

YF_Li123的博客 1682

R语言影像组学实战:从医学图像到预测模型的完整流程(附代码)

本文详细介绍了使用R语言进行影像组学分析的完整实战流程。从环境搭建、数据准备,到医学图像的特征提取与筛选,再到利用机器学习构建预测模型并进行评估,提供了清晰的步骤和可运行的R代码示例,帮助研究者和数据分析师掌握从医学图像到临床预测模型的核心技术。

qsc901234的博客 732

MapReduce二次排序

默认情况下,Map输出的结果会对Key进行默认的排序,但是有时候需要对Key排序的同时还需要对Value进行排序,这时候就要用到二次排序了。下面我们来说说二次排序 1、二次排序原理 我们把二次排序分为以下几个阶段 Map起始阶段 在Map阶段,使用job.setInputFormatClass()定义的InputFormat,将输入的数据集分割成小数据块spl...

913

银河麒麟V10系统下,手把手解决Ollama安装报错‘GLIBCXX_3.4.25 not found’

本文详细介绍了在银河麒麟V10系统下解决Ollama安装报错‘GLIBCXX_3.4.25 not found’的实战指南。通过隔离编译新版libstdc++、环境变量引导和服务化封装等安全方案,确保在不破坏系统稳定性的前提下顺利运行Ollama,适用于国产操作系统与AI工具的兼容性需求。

weixin_42556197的博客 484

无人船 | 基于ROS的轻量级多无人艇自主导航仿真框架

无人水面艇USV是海上自主无人系统的关键组成部分,在民用、军用领域应用广泛,例如海上救援、水质测量、扫雷反潜等,因此对USV导航算法的研究具有重要意义。为了便于进行USV相关算法的验证与部署,本文介绍的这套基于ROS的多无人艇的自主导航仿真平台,轻量化地实现了建图、规划、控制等多种功能,同时自研框架保证了功能的高度可拓展和可定制

FRIGIDWINTER的博客 8002

mapreduce二次排序

一、二次排序发生在需要对 Key 排序的同时再对 Value 进行排序的情况下。 主要分为以下几个阶段: Map 起始阶段 在Map阶段,使用 job.setInputFormatClass() 定义的 InputFormat ,将输入的数据集分割成小数据块 split,同时 InputFormat 提供一个 RecordReader的实现。本课程中使用的是 TextInputFormat,

ZoeYen_ 695

【C语言笔记初级篇】第一章:C语言快速入门及注意事项

(1)第一个C语言程序 A:利用vs2010写C语言程序 1:按以下步骤新建工程 2:添加源文件,“.c”文件 B:第一个C语言代码 1:以下是基本的C语言程序 2:由于没有设置连接器,所以打印结果没有显示,按照如下步骤链接控制台 (2)数据类型 A:基本数据类型及占用字节 B:一些概念的梳理 概念一:关于计算机的单位 位(bit):计算机通过电路的开关和闭合处理信息,电路通...

快乐江湖的博客 3737

MapReduce对数据进行二次排序

今天做了个用MapReduce对数据进行二次排序,这里的重点在于排序,所以要重写WritableComparator的排序方法compare方法,这里要注意一下的返回值如果返回-1就是升序排序,返回1就是降序排序。谨以此文章来记录自己的学习之路及希望能帮助到有需要的朋友。 题目要求: |1. 综合设计题 假设有两个文件代表两个班级的成绩,扩展名为.csv,文件中有两列数据,代表学号及数学成绩。具体...

weixin_43854618的博客 663

永恒之蓝漏洞复现(ms17-010)

Metasploit Framework(MSF)是一款开源安全漏洞检测工具,附带数千个已知的软件漏洞,并保持持续更新。Metasploit可以用来信息收集、漏洞探测、漏洞利用等渗透测试的全流程,被安全社区冠以“可以黑掉整个宇宙”之名。刚开始的Metasploit是采用Perl语言编写的,但是再后来的新版中,改成了用Ruby语言编写的了。在kali中,自带了Metasploit工具。

渗透之路,攻防之间皆学问 2万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

MapReduce高级应用——全排序和二次排序

前言 尽管现在MapReduce程序在日常开发中已经代码编写已经很少了,但作为大数据Hadoop的三大板块之一,他内在的许多思想也是很多后续框架的基础铺垫。本篇博客,南国重点回顾一下MR中的排序相关知识点。网上关于这个知识点 可能已经有很多的知识介绍,本来不打算写这篇博客。最近一段时间终于抽空看了Hadoop权威指南的大部分内容。于是,本篇博客 南国试着从面试回顾的角度去编写这篇博客。 话不多说,...

南国的技术栈 755

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MapReduce 二次排序总结

需求 1、输入数据: keyA 1 keyB 3 keyB 77 keyB 54 keyA 2 keyC 22 keyC 221 keyC 20 2、目标输出 keyA 1,2 keyB 3,54,77 keyC 20,22,221 解决思路 STEP 1. 改装Map结构,组合成一个新的Key值 MR框架不管是 默认排序 或者是 自定义排序 都只是对Key值进行排序,但我们可以将原始数据的K...

xw514124202的博客 445

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Hadoop MapReduce 实现二次排序

在优快云上看了很多做二次排序的,但总感觉自己看的都很蒙蔽,最后请教了老师,自己完成了二次排序,在这里和大家分享一下。 先上代码: 这个是我的 主函数、自定义mapper、自定义reducer public class myGameFive { public static void main(String [] args) throws IOException, ClassNotFoundException, InterruptedException { //设置一个config对象 连

Amo 317

MapReduce 二次排序

MapReduce 二次排序 需求: 有这样的一堆数据: 22 12 22 13 22 6 22 17 21 5 28 79 28 63 28 100 1 79 23 84 1 63 67 45 18 23 19 74 1 100 21 ...

TMH_ITBOY的博客 364

MapReduce的二次排序 SecondarySort

关于二次排序主要涉及到这么几个东西: 在0.20.0 以前使用的是 setPartitionerClass  setOutputkeyComparatorClass setOutputValueGroupingComparator   在0.20.0以后使用是 job.setPartitionerClass(Partitioner p); job.se

爱篮球的IT小青年~ ~ 881

使用MapReduce进行二次排序

首先进行hadoop集群的hdfs,yarn等的相关配置,配置成功之后。进行如下操作: 1 启动Hadoop 执行命令启动前面实验部署好的Hadoop系统。 [root@master ~]# cd /usr/cstor/hadoop/ [root@master hadoop]# sbin/start-all.sh 使用jps分别查看master的Java进程如下: 使用jps...

qq_40371180的博客 1103

mapreduce排序_二次排序

二次排序Partitioner、SortComparator、GroupingComparator Partitioner:完成分区,重写getPartition()函数 SortComparator与GroupingComparator异同: 相同:都要继承WritableComparator对象,构造函数关联bean对象,重写compare()方法. 不同:SortComparator完成的是...

Charles_D 328
上一篇: Spark JDBC读取数据分区数源码跟踪
下一篇: spark内存管理源码解读(基于Spark1.6)
斜杆小刘
博客等级 码龄10年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值