上一篇博客说明了怎么自定义Key,而且用了二次排序的例子来做测试,但没有详细的说明二次排序,这一篇说详细的说明二次排序,为了说明曾经一个思想的误区,特地做了一个3个字段的二次排序来说明。后面称其为“三次排序”。
测试数据:
a1,b2,c5
a4,b1,c3
a1,b2,c4
a2,b2,c4
a2,b1,c4
a4,b1,c2
测试目的:输出以下结果首先根据第一个自段排序,如果第一个字段排好后再根据第二个字段的升序排序最后在根据第三个字段进行排序,得到以下结果。
a1      b2,c4
a1      b2,c5
a2      b1,c4
a2      b2,c4
a4      b1,c2
a4      b1,c3
之所以会设置三个字段,是想说明一个曾经困扰我很久的问题,问题大概描述如下:以下网上学习某大神讲的mapreduce时他对二次排序原理的一段描述
二次排序原理
在map阶段,使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordReder的实现。本例子中使用的是TextInputFormat,他提供的RecordReader会将文本的字节偏移量作为key,这一行的文本作为value。这就是自定义Map的输入是<LongWritable, Text>的原因。然后调用自定义Map的map方法,将一个个<LongWritable, Text>对输入给Map的map方法。注意输出应该符合自定义Map中定义的输出<IntPair, IntWritable>。最终是生成一个List<IntPair, IntWritable>。
排序的过程:(当时理解的第一次排序,只排序自定义类型中的第一个字段)
在map阶段的最后,会先调用job.setPartitionerClass对这个List进行分区,每个分区映射到一个reducer。每个分区内又调用job.setSortComparatorClass设置的key比较函数类排序。可以看到,这本身就是一个二次排序。 如果没有通过job.setSortComparatorClass设置key比较函数类,则使用key的实现的compareTo方法。 
排序的过程:(当时理解的第二次排序,排序自定义类型中的第二个字段)
在reduce阶段,reducer接收到所有映射到这个reducer的map输出后,也是会调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序。然后开始构造一个key对应的value迭代器。这时就要用到分组,使用job.setGroupingComparatorClass设置的分组函数类(如果没设置则会判断是否Key中所有的字段是否都相同,比较整个对象流的字节)。只要这个比较器比较的两个key相同,他们就属于同一个组,它们的value放在一个value迭代器,而这个迭代器的key使用属于同一个组的所有key的第一个key。最后就是进入Reducer的reduce方法,reduce方法的输入是所有的(key和它的value迭代器)。同样注意输入与输出的类型必须与自定义的Reducer中声明的一致。 
核心总结:
1、map最后阶段进行partition分区,一般使用job.setPartitionerClass设置的类,如果没有自定义Key的hashCode()方法进行分区。
2、每个分区内部调用job.setSortComparatorClass设置的key的比较函数类进行排序,如果没有则使用Key的实现的compareTo方法。
3、当reduce接收到所有map传输过来的数据之后,调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序,如果没有则使用Key的实现的compareTo方法。
4、紧接着使用job.setGroupingComparatorClass设置的分组函数类,进行分组,同一个Key的value放在一个迭代器里面。如果未指定GroupingComparatorClass则则使用Key的实现的compareTo方法来对其分组。
以下是我刚开始思考的二次排序的数据流时的错误的想法:如果是多个map对同一个reduce发数据:数据流不就成为下面这样了
a4,b4                               a3,b3
a3,b3                               a4,b4
         ---------------------->
a2,b1                               a1,b2
a1,b2                               a2,b1
如果reduce 接收到上一整块数据,那么hadoop框架便会在对第一个字段排序,什么时候对第二个字段排的序呢,但为什么结果又是排过序的呢
所以我做了本例的实验,用三个字段来排序,实验的结果就是本例的结果,最后还是感叹自己学艺不精啊,排序的本质不就是根据compareTo做完整的比做吗
所以从map端到reduce端的数据应该是这样的:已经做一次完整的排序了
a4,b4                               a3,b3
a3,b3                               a4,b4
         ---------------------->
a2,b1                               a1,b1
a1,b2                               a2,b2
---------------------
作者:doegoo
来源:CSDN
原文:https://blog.csdn.net/doegoo/article/details/50377752
版权声明:本文为博主原创文章,转载请附上博文链接!

关于MapReduce二次排序的一点解答的更多相关文章

  1. Hadoop学习笔记: MapReduce二次排序

    本文给出一个实现MapReduce二次排序的例子 package SortTest; import java.io.DataInput; import java.io.DataOutput; impo ...

  2. (转)MapReduce二次排序

    一.概述 MapReduce框架对处理结果的输出会根据key值进行默认的排序,这个默认排序可以满足一部分需求,但是也是十分有限的.在我们实际的需求当中,往往有要对reduce输出结果进行二次排序的需求 ...

  3. 详细讲解MapReduce二次排序过程

    我在15年处理大数据的时候还都是使用MapReduce, 随着时间的推移, 计算工具的发展, 内存越来越便宜, 计算方式也有了极大的改变. 到现在再做大数据开发的好多同学都是直接使用spark, hi ...

  4. MapReduce二次排序

    默认情况下,Map 输出的结果会对 Key 进行默认的排序,但是有时候需要对 Key 排序的同时再对 Value 进行排序,这时候就要用到二次排序了.下面让我们来介绍一下什么是二次排序. 二次排序原理 ...

  5. Hadoop MapReduce 二次排序原理及其应用

    关于二次排序主要涉及到这么几个东西: 在0.20.0 以前使用的是 setPartitionerClass setOutputkeyComparatorClass setOutputValueGrou ...

  6. mapreduce二次排序详解

    什么是二次排序 待排序的数据具有多个字段,首先对第一个字段排序,再对第一字段相同的行按照第二字段排序,第二次排序不破坏第一次排序的结果,这个过程就称为二次排序. 如何在mapreduce中实现二次排序 ...

  7. MapReduce 二次排序

    默认情况下,Map 输出的结果会对 Key 进行默认的排序,但是有时候需要对 Key 排序的同时再对 Value 进行排序,这时候就要用到二次排序了.下面让我们来介绍一下什么是二次排序. 二次排序原理 ...

  8. java mapreduce二次排序

    原文链接: https://www.toutiao.com/i6765808056191156748/ 目的: 二次排序就是有下面的数据 a 3 a 1 a 100 c 1 b 2 如果只按照abc排 ...

  9. Hadoop学习之自定义二次排序

    一.概述    MapReduce框架对处理结果的输出会根据key值进行默认的排序,这个默认排序可以满足一部分需求,但是也是十分有限的.在我们实际的需求当中,往 往有要对reduce输出结果进行二次排 ...

随机推荐

  1. 前端开发-1React-1概述

    React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站.做出来以后,发现这套东西很 ...

  2. iOS12系统应用发送普通邮实现发送

    iOS12系统应用发送普通邮实现发送 构建好邮件以后,可以发送该邮件.此时需要使用mailComposeDelegate属性,该属性用来设置委托,其语法形式如下: unowned(unsafe) va ...

  3. Springboot中使用Scheduled做定时任务

    在开发中,定时任务是常见的功能,在spring boot 下开发定时任务其实很简单,具体代码如下: 1.配置依赖包pom.xml 由于默认的maven仓库经常访问不了,这里采用了阿里云的maven仓库 ...

  4. Android源代码下载 “Gerrit下载源代码”

    repo init -u ssh://jenkins@gerrit.y:29419/manifest -m k86A.xml 使用-m参数指定具体使用的是k86A.mxl文件 步骤1. curl ht ...

  5. Zepto.js_开始

    https://zeptojs.com 轻量级的 JavaScript 库,移动端优先框架 针对移动端,处理了一系列如 click 点击延迟 毫秒 响应执行快 目前 API 完善的框架中体积最小的一个 ...

  6. 微信公众号_订阅号_微信JS-SDK网页开发

    微信JS-SDK( 分享接口很常用 ) 是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包 借助微信高效使用相机.语音.选题.位置等手机系统的能力,同时可以直接使用微信分享.扫一扫.支付等 ...

  7. amazeui表单form异步提交方法

    // 留言提交 $(function() { var $form = $('#ue-form'); $form.validator({ validateOnSubmit: true, submit: ...

  8. linux locate命令

    1.命令简介         locate(locate) 命令用来查找文件或目录. locate命令要比find -name快得多,原因在于它不搜索具体目录,而是搜索一个数据库/var/lib/ml ...

  9. 小程序上拉加载更多数据(onReachBottom)

    <!--pages/test/test.wxml--> <block wx:for="{{list}}" wx:key="item.id"&g ...

  10. Python 学习笔记6 变量-字典

    字典是python中一个十分重要的变量,他是一个可变的容器对象.通过一组key(键)和value(值)对组成一个元素. 组成形式为{'key':'value', 'key':'value'}.整个字典 ...