实验目的

理解mapreduce的工作原理

理解Partitioner的书写方法

理解GroupingComparator的书写方法

实验原理

  我们已经学习了hadoop的大部分基础知识,剩下的就是利用hadoop解决实际的业务问题。首先我们回顾一下mapreduce的工作过程:
  数据通过InputFormat中定义的RecordReader读进来,然后以键值对的形式写出去,在map中进行处理,map处理完成后以键值对的形式写出,中途经过分区、分组、排序后,将key相同的value放进一个迭代器传给reduce,每个reduce任务处理的数据是key相同的一组value构成的的迭代器。

1.实现单词计数
  首先我们要实现单词计数的程序,首先map端将读入的数据分割成单词,然后以单词为key,1为value写出,reduce拿到的数据就是以单词为key,这个单词对应的所有的1组成的迭代器为value,我们将所有的value加起来就是这个单词的数量。
  单词计数是最简单也是最能体现MapReduce思想的程序之一,可以称为MapReduce版"Hello World"。单词计数主要完成功能是:统计一系列文本文件中每个单词出现的次数,如下图所示:

2.实现自定义分区
  我们有时候希望能够按照自己的意愿合理分配每个reduce计算的单词,比如我想最后把所有的以字母A开头的单词单独输出,这时候就需要自定义分区,将key中以A开头的单词放进一个给定的reduce。自定义分区需要定义一个类,继承自Partitioner或者Partitioner的子类,实现getPartition方法,按照业务需求分配不同key分配到的reduce。

3.实现按照字母多少排序
  统计单词个数业务不难,但是我们希望对结果进行排序输出。当然我们可以在程序执行结束以后使用shell、Python等工具进行排序,但是我们也可以直接使用mapreduce自带的排序组件,使用mapreduce自带的GroupingComparator能利用mapreduce框架帮我们排序。

4.mapreduce的工作步骤
  数据通过InputFormat中定义的RecorderReader读进来,然后以键值对的形式<key,value style="box-sizing: border-box;">传进map程序,map处理完成后以<key,value style="box-sizing: border-box;">的形式写出,传入哪个reduce根据自定义的Partitioner决定,传入每一个reducer的数据,key一样的键值对的value会放进一个迭代器,在这个判断key是否一样的就是根据自定义的GroupingComparator。会根据key的compare方法进行排序。

5.Partitioner的书写方法
  我们自定义的Partitioner需要继承自一个Partitioner类,实现getPartition方法,getPartition的签名为:public abstract int getPartition(KEY key, VALUE value, int numPartitions),其中key和value是map程序写出的键值对,numPartitions是reduce的个数,通过程序代码设置,返回值就是reduce的index。

6.GroupingComparator的书写方法
  map输出的键值对中,key相同的value会被放进同一个迭代器,也就是按照key分组,而判断key是否相等的规则是我们通过GroupingComparator设置的,通过重写compare方法,就能修改判断逻辑。

实验环境

1.操作系统
  服务器:Linux_Centos
  操作机:Windows_7
  服务器默认用户名:root,密码:123456
  操作机默认用户名:hongya,密码:123456
2.实验工具
  IntelliJ IDEA

IDEA全称IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE支持、Ant、JUnit、CVS整合、代码审查、创新的GUI设计等方面的功能可以说是超常的。IDEA是JetBrains公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

  优点:
1)最突出的功能自然是调试(Debug),可以对Java代码,JavaScript,JQuery,Ajax等技术进行调试。其他编辑功能抛开不看,这点远胜Eclipse。
2)首先查看Map类型的对象,如果实现类采用的是哈希映射,则会自动过滤空的Entry实例。不像Eclipse,只能在默认的toString()方法中寻找你所要的key。
3)其次,需要动态Evaluate一个表达式的值,比如我得到了一个类的实例,但是并不知晓它的API,可以通过Code Completion点出它所支持的方法,这点Eclipse无法比拟。
4)最后,在多线程调试的情况下,Log on console的功能可以帮你检查多线程执行的情况。

  缺点:
1)插件开发匮乏,比起Eclipse,IDEA只能算是个插件的矮子,目前官方公布的插件不足400个,并且许多插件实质性的东西并没有,可能是IDEA本身就太强大了。
2)在同一页面中只支持单工程,这为开发带来一定的不便,特别是喜欢开发时建一个测试工程来测试部分方法的程序员带来心理上的不认同。
3)匮乏的技术文章,目前网络中能找到的技术支持基本没有,技术文章也少之又少。
4)资源消耗比较大,建个大中型的J2EE项目,启动后基本要200M以上的内存支持,包括安装软件在内,差不多要500M的硬盘空间支持。(由于很多智能功能是实时的,因此包括系统类在内的所有类都被IDEA存放到IDEA的工作路径中)。

  特色功能:
  智能选择
  丰富的导航模式
  历史记录功能
  JUnit的完美支持
  对重构的优越支持
  编码辅助
  灵活的排版功能
  XML的完美支持
  动态语法检测
  代码检查等等。

步骤1:自定义输出类

  本次实验的代码放在包hellohadoop项目的com.hongya.day025下。我们可以进入D:/hongya/ideaspace/hellohadoop/src/com/hongya/day025查看源代码。

  1.1我们需要排序,首先要定义自己的输出类,自定义输出类需要包含单词和计数,如下:

public class WordCount implements WritableComparable<WordCount> {

private String word;

private long count;

// getset方法、构造方法省略

@Override

public int compareTo(WordCount o) {

int i = - Long.compare(count,o.count);

if (i != 0){

return i;

}

return word.compareTo(o.word);

}

@Override

public void write(DataOutput out) throws IOException {

out.writeUTF(word);

out.writeLong(count);

}

@Override

public void readFields(DataInput in) throws IOException {

word = in.readUTF();

count = in.readLong();

}

  我们需要实现compareTo方法,作为Reduce内部的排序方法,还要定义读写的方法

  1.2自定义分区和分组,实现按照单词出现的次数排序。
  我们想要map完成后的数据能够按照计数排序,因为排序只能在每一个reduce内部进行,所以我们需要输入到每一个reduce的数据不能是乱的。设计partition应该合理考虑这点,根据单词的计数进行分区。

@Override

public int getPartition(WordCount key, NullWritable value, int numReduceTasks) {

if (numReduceTasks == 1){

return 0;

}

if (key.getCount() < numReduceTasks){

return (int) key.getCount();

}

return numReduceTasks - 1;

}

  首先判断reduce的数量,如果是1就不用计算,每个reduce只计算对应的count,当count比较大,全都给最后一个reduce计算,当然你可以自定义更好的分区方式。

  1.3自定义分组函数。
  显然我们分组就是为了让所有计数一样的都进同一个组,所以逻辑就是只比较计数,忽略单词.

@Override

public int compare(WritableComparable a, WritableComparable b) {

WordCount o1 = (WordCount) a;

WordCount o2 = (WordCount) b;

return Long.compare(o1.getCount(),(o2.getCount()));

}

吴裕雄--天生自然HADOOP操作实验学习笔记:Wor的Count程序的编写的更多相关文章

  1. 吴裕雄--天生自然HADOOP操作实验学习笔记:分布式及RPC通信简介

    实验目的 掌握GOF设计模式的代理模式 了解掌握socket编程.java反射.动态代理 了解NIO.多线程 掌握hadoop的RPC框架使用API 实验原理 1.什么是RPC 在hadoop出现以前 ...

  2. 吴裕雄--天生自然HADOOP操作实验学习笔记:pig简介

    实验目的 了解pig的该概念和原理 了解pig的思想和用途 了解pig与hadoop的关系 实验原理 1.Pig 相比Java的MapReduce API,Pig为大型数据集的处理提供了更高层次的抽象 ...

  3. 吴裕雄--天生自然HADOOP操作实验学习笔记:使用hive操作hbase

    实验目的 熟悉hive和hbase的操作 熟悉hadoop.hbase.hive.zookeeper的关系 熟练大数据环境的搭建 学会分析日志排除问题 实验原理 1.hive整合hbase原理 前面大 ...

  4. 吴裕雄--天生自然HADOOP操作实验学习笔记:mapreduce代码编程

    实验目的 深入了解mapreduce的底层 了解IDEA的使用 学会通过本地和集群环境提交程序 实验原理 1.回忆mapreduce模型 前面进行了很多基础工作,本次实验是使用mapreduce的AP ...

  5. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase学生选课案例

    实验目的 复习hbase的shell操作和javaAPI操作 了解javaWeb项目的MVC设计 学会dao(数据库访问对象)和service层的代码编写规范 学会设计hbase表格 实验原理 前面我 ...

  6. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase的javaAPI应用

    实验目的 进一步了解hbase的操作 熟悉使用IDEA进行java开发 熟悉hbase的javaAPI 实验原理 前面已经了解通过hbase的shell操作hbase,确实比较难以使用,另外通过hiv ...

  7. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase的shell应用v2.0

    HRegion 当表的大小超过设置值的时候,HBase会自动地将表划分为不同的区域,每个区域包含所有行的一个子集.对用户来说,每个表是一堆数据的集合,靠主键来区分.从物理上来说,一张表被拆分成了多块, ...

  8. 吴裕雄--天生自然HADOOP操作实验学习笔记:hive DDL

    实验目的 了解hive DDL的基本格式 了解hive和hdfs的关系 学习hive在hdfs中的保存方式 学习一些典型常用的hiveDDL 实验原理 有关hive的安装和原理我们已经了解,这次实验我 ...

  9. 吴裕雄--天生自然HADOOP操作实验学习笔记:mapreduce和yarn命令

    实验目的 了解集群运行的原理 学习mapred和yarn脚本原理 学习使用Hadoop命令提交mapreduce程序 学习对mapred.yarn脚本进行基本操作 实验原理 1.hadoop的shel ...

  10. 吴裕雄--天生自然HADOOP操作实验学习笔记:hdfs简单的shell命令

    实验目的 了解bin/hadoop脚本的原理 学会使用fs shell脚本进行基本操作 学习使用hadoop shell进行简单的统计计算 实验原理 1.hadoop的shell脚本 当hadoop集 ...

随机推荐

  1. 具体的client-server通信模型以及最为常用的通信模式

    实现虚拟网络服务的主要技术,指出IP负载均衡技术是在负载调度器的实现技术中效率最高的. 在已有的IP负载均衡技术中: 1)有通过网络地址转换(Network Address Translation)将 ...

  2. mui下拉刷新 ios click事件无法响应问题

    使用mui的事件监听事件 tap mui("#pullrefresh").on('tap', '.ulDiv', function (event) {this.click();}) ...

  3. C语言:对长度为7的字符串,除首尾字符外,将其余5个字符按ASCII降序排序。-计算并输出3~n之间所有素数的平方根之和。

    //对长度为7的字符串,除首尾字符外,将其余5个字符按ASCII降序排序. #include <stdio.h> #include <ctype.h> #include < ...

  4. Codeforces Round #576 (Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1199 A. City Day 题意:给出一个数列,和俩个整数\(x,y\),要求找到序号最靠前的数字\(d\),使得\(d\)满足 ...

  5. linux下的apache服务自启动的几种方式

    1,如果是安装包安装在Linux系统下,那么可以使用 [root@localhost ~]# service httpd restart 从而可以开启或者重启apache服务 与此同时,它的标准方式是 ...

  6. 新建文件的UID和GID

    默认情况下:新建文件的用户ID为操作当前文件进程的有效用户ID(参考以前文章),新建文件的组ID为操作当前文件的进程的有效组ID 特殊情况:当当前新建文件的目录的SET-GID位被设置时,那么新建文件 ...

  7. git合并分支到master上面

    转自:https://www.cnblogs.com/mafeng/p/10173919.html 假如我们现在在dev分支上,刚开发完项目,执行了下列命令 git add .git commit - ...

  8. java与以太坊之web3j

    web3j:https://docs.web3j.io/index.html 如何使用Web3j生成私钥和地址,而不只是创建密钥存储JSON文件? https://blog.csdn.net/mong ...

  9. Java 中序列化与反序列化引发的思考?

    java 中序列化指从对象转变为 二进制流的过程中需要进行序列化,而反序列化指二进制流转换为java 对象.那么有的时候java 存储到数据库不需要序列化, 而计算机系统本质存储的就是二进制文件,数据 ...

  10. 刚开始用springboot踩的好多坑!!!

    今天,刚开始就在刚才我留下了激动的泪水,因为我捯饬springboot已经有几天了,我通过看视频学的,但是坑实在是太多了,今年是鼠年~~~LOL----瘟疫之源来了, 被困在了老家不能走,老家网实在是 ...