• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
导航菜单
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx
您的位置:首页 > 服务器 >云计算 > MapReduce处理二次排序(分区-排序-分组),mapreduce二次

MapReduce处理二次排序(分区-排序-分组),mapreduce二次

作者:网友 字体:[增加 减小] 来源:互联网

本文主要包含mapreduce 分区,mapreduce排序,mapreduce二次排序,mapreduce 全排序,mapreduce实现排序等服务器相关知识,网友希望可以进行参考

MapReduce处理二次排序(分区-排序-分组),mapreduce二次


MapReduce二次排序原理

在map阶段,使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordReader的实现。
本例子中使用的时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相同,他们就属于同一个组,他们的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放在一个迭代器里面

分区 --->  排序(二次)  --->  分组
分区默认的是key的hashcode()
排序默认的实key的compareTo()

-----------------------------------------

job.setPartitionerClass(Partitioner p); //设置分区。默认分区时hashcode()
job.setSortComparatorClass(RawComparator c);  //比较排序。shuffle阶段map输出之后,reduce之前。默认是key的compareTo()方法
job.setGroupingComparatorClass(RawComparator c); //分组。Reduce阶段

-----------------------------------------

案例

原始数据

2 12:12:34 2_hao123
3 09:10:34 3_baidu
1 15:02:41 1_google
3 22:11:34 3_sougou
1 19:23:23 1_baidu
2 13:56:60 2_soso

分别依据第一列和第二列对数据进行二次排序

1.分区类

package test.mr.seconderysort;

import org.apache.hadoop.io.Text;

/*
 * 分区类
 */
public class Partitioner extends
		org.apache.hadoop.mapreduce.Partitioner<StringPart, Text> {

	@Override
	public int getPartition(StringPart key, Text value, int numPartitions) {
		// TODO Auto-generated method stub
		return Math.abs(key.hashCode()) % numPartitions;
	}

}


 

2.自定义Map输出的key类,将原始数据要排序的两列作为该JavaBean的属性,实现WritableComparable接口,实现CompareTo()排序方法

Ps:WritableComparatable接口中的CompareTo()方法:在这个方法中,如果返回-1,则当前对象排前面,返回1,就排后面 ,0,就相等。

String类中的CompareTo()方法:

/*
  * compareTo()的返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.
  *
  * 例:  String s1 = "abc";
  *     String s2 = "abcd";
  *     String s3 = "abcdfg";
  *     String s4 = "1bcdfg";
  *     String s5 = "cdfg";
  *     System.out.println( s1.compareTo(s2) );// -1 (前面相等,s1长度小1)
  *     System.out.println( s1.compareTo(s3) ); //-3 (前面相等,s1长度小3)
  *     System.out.println( s1.compareTo(s4) ); //48("a"的ASCII码是97,"1"的的ASCII码是49,所以返回48)
  *     System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)
  */

package test.mr.seconderysort;

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

import org.apache.hadoop.io.WritableComparable;

/*
 * 自定义key
 */
/*
 *如果想对自己写的类排序,你就把自己写的这个类实现Comparable接口
 *然后写一个comparaTo方法来规定这个类的对象排序的顺序。
 *在这个方法中,如果返回-1,则当前对象排前面,返回1,就排后面 ,0,就相等
 */
public class StringPart implements WritableComparable<StringPart> {
	/*
	 * 两列排序
	 */
	private String first;
	private String second;

	public String getFirst() {
		return first;
	}

	public void setFirst(String first) {
		this.first = first;
	}

	public String getSecond() {
		return second;
	}

	public void setSecond(String second) {
		this.second = second;
	}

	public StringPart() {
		super();
		// TODO Auto-generated constructor stub
	}

	public StringPart(String first, String second) {
		super();
		this.first = first;
		this.second = second;
	}

	@Override
	public void write(DataOutput out) throws IOException {
		out.writeUTF(first);
		out.writeUTF(second);

	}

	@Override
	public void readFields(DataInput in) throws IOException {
		this.first = in.readUTF();
		this.second = in.readUTF();
	}

	/*
	 * 排序
	 */
	/*
	 * compareTo()的返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的
	 * 
	 * 差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方
	 * 
	 * 全比较完,这时就比较字符的长度.
	 * 
	 * 例:  String s1 = "abc";
	 *     String s2 = "abcd"; 
	 *     String s3 = "abcdfg"; 
	 *     String s4 = "1bcdfg"; 
	 *     String s5 = "cdfg"; 
	 *     System.out.println( s1.compareTo(s2) );// -1 (前面相等,s1长度小1) 
	 *     System.out.println( s1.compareTo(s3) ); //-3 (前面相等,s1长度小3) 
	 *     System.out.println( s1.compareTo(s4) ); //48("a"的ASCII码是97,"1"的的ASCII码是49,所以返回48) 
	 *     System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)
	 */
	@Override
	public int compareTo(StringPart o) {
		if (!this.first.equals(o.getFirst())) {
			return first.compareTo(o.getFirst()); // 字符串的compareTo()方法
		} else {
			if (!this.second.equals(o.getSecond())) {
				return second.compareTo(o.getSecond());
			} else {
				return 0;
			}
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((first == null) ? 0 : first.hashCode());
		result = prime * result + ((second == null) ? 0 : second.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		StringPart other = (StringPart) obj;
		if (first == null) {
			if (other.first != null)
				return false;
		} else if (!first.equals(ot
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • [Hive]MapReduce将数据写入Hive分区表,mapreducehive
  • MapReduce处理二次排序(分区-排序-分组),mapreduce二次

相关文章

  • Docker在Ubuntu的部署实践,dockerubuntu部署
  • Hive学习笔记(二),hive学习笔记
  • hadoop学习笔记(六)——hadoop2.5.2全分布模式实现的部署,hadoophadoop2.5.2
  • 你真的很熟分布式处理和事务吗?,事务
  • 大数据流式处理一个不能忽视的问题,数据流不能忽视
  • kernel syn,syn
  • Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.1,mllibconvolution
  • springmvc No mapping found for HTTP request with URI in Dispatc,springmvcdispatc
  • Hadoop之——Java操作HBase,hadoopjavahbase
  • hive:Access denied for user &#39;root&#39;@&#39;%&#39;,hivedenied

文章分类

  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx

最近更新的内容

    • zookeeper——分布式锁,zookeeper
    • Andrew Ng机器学习课程10补充,andrewng
    • Hive 外部表 分区表,hive外部表分区表
    • LXC学习,学习中国app上线
    • 关于Oozie的input-events和done-flag,oozieinput-events
    • Mellanox网卡,使用netperf进行性能测试,mellanoxnetperf
    • -bash:jps:command not found,-bashjps
    • hdfs一致性模型,hdfs一致性
    • Linux如何上线和下线CPU,Linux上线下线CPU
    • AWS EC2 调整云主机根卷大小,awsec2

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有